浅谈ArrayList类toArray方法

在这里插入图片描述
list转数组可以通过调用toarray的两种重载完成,这里主要讨论一下第二种有参的方法,具体的使用仅大概介绍一下

使用形式:

		ArrayList<Integer> list=new ArrayList<>();
		Integer[] a;

		//1.存在问题:“将 'arr.toArray()' 转换为 'Integer[]' 会为任意非 null 值生成 'ClassCastException'”
		//也就是将返回的obj【】强转为integer【】,要求list里面没有null值才能这样
		a= (Integer[]) list.toArray();
		//2.使用含参的,参数是一个空的T[]数组,这种是最好使的
		a=list.toArray(new Integer[0]);
		//3.含参,但参数是一个已有的数组——这就容易出问题了,也就是这篇要讨论的地方
		a=list.toArray(b);

推荐是使用第二种,但是第三中种问题在哪呢——看源码
作为对比,先看无参方法:

public Object[] toArray() {
        return Arrays.copyOf(elementData, size);
    }
    //ctrl+b
public static <T> T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());
    }
    //ctrl+b
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        @SuppressWarnings("unchecked")
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

可以看到这里的newlength参数,? (T[]) new Object[newLength]说明返回的obj数组,长度就是list内元素的长度(elementdata是list内存储数据的数组,size是存储数据的个数,即list.size()就是直接返回size),然后将list元素都copy过去返回。

而含参方法:

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());
        System.arraycopy(elementData, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }

可以看到,如果参数数组T[]的长度小于list内元素的个数,那么就和无参的差不多,只不过是额外指定了返回值的类型;这也就是上面说的第二种推荐的方法。
但如果a.length > size,就有问题了——arraycopy仍然,但是a[size] = null;
什么意思呢——这并不是像c里的数组,说把它截断成size那么长,而就是仅仅给size位置赋一个null值,这就很坑了。

尤其是参数a就是接收结果的数组,或者其他有用的数组的情况:如果是其他有用的数组,里面的数据会被直接覆盖成list的内容,而且长度超过size的话并不会被截短;如果是a=list.toArray(a);,当a长度小于size还好,如果超过,那么返回的数组里面可能仍然有原先不需要的数据,而且仅靠一个null值分割(有个null本身就很不好了),这对于后面遍历数组操作的时候是很要命了。

测试结果:
在这里插入图片描述

在这里插入图片描述
(原数据被覆盖了,而且length也没有变短)

结论:千万不要图省事,写个a=list.toArray(a);,那个参数一定多打几个字写成new Integer[0]

另:有时候需要的是int数组,而list只能得到integer数组——强制转换是不行的,这里给一种办法(试了下,性能并不是很快,大佬有其他办法的话教教):

arr = Arrays.stream(integerArr).mapToInt(Integer::intValue).toArray();
//上面那个不能处理null值,如果可能有null的话下面这个将null变为0
arr = Arrays.stream(integerArr).mapToInt(i -> i != null ? i : 0).toArray();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值