浅谈集合转换成数组的方法--toArray()与toArray(T[] a)

众所周知,ArrayList 集合的底层是通过数组来实现的,但是集合与数组还是有一些区别的,简单来说,集合的长度是可变的,而数组的长度是不可变的,通过这点可以引发出一点效率上的差异,当所处理的数据长度已知不变时,推荐用数组对其进行处理,当长度不可预知时,也只好通过集合对其进行处理。

集合转换成数组通常使用toArray()方法,这个方法还有一个重载方法为toArray(T[] a),本文主要根据以下两部分简单谈谈这两个方法的使用及区别。

第一部分为源码简析,第二部分为Demo展示。


第一部分:简单说明两个方法的源码


第一个:toArray()


下面是ArrayList类toArray()方法的源码:

public Object[] toArray() {
        return Arrays.copyOf(elementData, size);
    }

可以看出在toArray()方法中是通过Arrays工具类对其进行copyOf()方法的调用进行数据的拷贝,并返回一个Object类型的数组


copyOf方法的源码:

public static <T> T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());
    }

第二个:toArray(T[] a)


下面是重载的第二个方法的源码:

 public <T> T[] toArray(T[] a) {
        if (a.length < size)
            // Make a new array of a's runtime type, but my contents:
            return (T[]) Arrays.copyOf(elementData, size, a.getClass());
<strong><span style="color:#ff0000;">        System.arraycopy(elementData, 0, a, 0, size);</span></strong>
        if (a.length > size)
            a[size] = null;
        return a;
    }


可以看出,这个重载方法可以接收一个类型的数组,然后分为两种情况进行操作:


1.如果传入的数组长度不小于集合的长度(size),则集合里的数据(elementData),集合的实际长度(size),及集合的泛型(a.getClass())传入到Arrays的copyOf方法,通过方法创建一个长度与集合长度一样的新数组,并将集合里的数据拷贝到新数组中,并转型成集合的泛型的类型,将数组返回。下面是copyOf方法的源码:


public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
<strong><span style="color:#ff0000;">        System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));</span></strong>
        return copy;
    }

可以看出,这个重载方法可以接收一个类型的数组,然后分为两种情况进行操作,如果传入的数组长度不小于集合的长度(size),则集合里的数据(elementData),集合的实际长度(size),及集合的泛型(a.getClass())传入到Arrays的copyOf方法,通过方法创建一个长度与集合长度一样的新数组,并将集合里的数据拷贝到新数组中,并转型成集合的泛型的类型,将数组返回。下面是copyOf方法的源码:



2.如果传入的数组长度大于集合的长度(size),将集合里的元素直接进行拷贝,多余的元素赋值为null。


通过红色标注的源码可知,两种情况的拷贝方式是一样的,只是有一种情况会产生新的数组实例


第二部分:简单Demo展示

注:由于第一个方法toArray()很简单,就不做展示,主要展示第二个方法toArray(T[] a)传入的数组长度是否大于集合长度的情况。

第一个例子:传入的数组长度不小于集合的长度

	public static void main(String[] args) {

		List<User> userList = new ArrayList<User>();

		User u1 = new User(1, "ted", "nan", 24);
		userList.add(u1);
		User u2 = new User(2, "mead", "nan", 27);
		userList.add(u2);
		User u3 = new User(3, "tead", "nan", 21);
		userList.add(u3);
		User u4 = new User(4, "yead", "nan", 15);
		userList.add(u4);

		User[] u = new User[5];

		User[] us = userList.toArray(u);

		for (int i = 0; i < us.length; i++) {
			System.out.println(us[i]);
		} 
<span style="white-space:pre">		</span>System.out.println(us == u);
	}

例子很简单,创建一个泛型为User的集合,集合里存入四个User对象,并创建一个长度为5的数组,传入方法进行调用,然后输出数组中的数据,最后通过"=="的方式判断两个数组是否一致。下面是程序的输出结果:


User [id=1, name=ted, gender=nan, age=24]
User [id=2, name=mead, gender=nan, age=27]
User [id=3, name=tead, gender=nan, age=21]
User [id=4, name=yead, gender=nan, age=15]
null
<strong><span style="color:#ff0000;">true</span></strong>

可以看出4个对象存入数组中,传入的数组长度大于集合的长度,所以第五个值为null,并且没有创建新的数组对象,所以两个数组对象判断结果为true


第二个例子:传入的数组长度小于集合的长度

<span style="white-space: pre;">	</span>public static void main(String[] args) {

		List<User> userList = new ArrayList<User>();

		User u1 = new User(1, "ted", "nan", 24);
		userList.add(u1);
		User u2 = new User(2, "mead", "nan", 27);
		userList.add(u2);
		User u3 = new User(3, "tead", "nan", 21);
		userList.add(u3);
		User u4 = new User(4, "yead", "nan", 15);
		userList.add(u4);

		User[] u = new User[3];

		User[] us = userList.toArray(u);

		for (int i = 0; i < us.length; i++) {
			System.out.println(us[i]);
		}

		System.out.println(us == u);
	}

第二个例子与上一个类似,只是将数组的长度变为3,小于集合的长度,下面是程序的输出结果:


User [id=1, name=ted, gender=nan, age=24]
User [id=2, name=mead, gender=nan, age=27]
User [id=3, name=tead, gender=nan, age=21]
User [id=4, name=yead, gender=nan, age=15]
<strong><span style="color:#ff0000;">false</span></strong>

可以看出,四个User对象也都转成了数组的形式输出出来,并且最后的判断结果为false,表示第二个数组us指向了一个新的数组实例,而不是传入的数组u。


两个方法简单总结:

1.toArray()方法无需传入参数,可以直接将集合转换成Object数组进行返回,而且也只能返回Object类型

2.toArray(T[] a)方法需要传入一个数组作为参数,并通过泛型T的方式定义参数,所返回的数组类型就是调用集合的泛型,所以自己无需再转型,但是根据传入数组的长度    与集合的实际长度的关系,会有不同的处理;

    a:数组长度不小于集合长度,直接拷贝,不会产生新的数组对象;

    b:数组长度小于集合长度,会创建一个与集合长度相同的新数组,将集合的数据拷贝到新数组并将新数组的引用返回。


  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值