使用集合转数组的方法,必须使用集合的 toArray(T[] array)方法,传入的是类型完全一致、长度为 0 的空数组。
反例:
直接使用 toArray 无参方法存在问题,此方法返回值只能是 Object[]类,若强转其它类型数组将出现ClassCastException 错误。
正例:
说明:使用 toArray 带参方法,数组空间大小的 length:
1) 等于 0,动态创建与 size 相同的数组,性能最好。
2) 大于 0 但小于 size,重新创建大小等于 size 的数组,增加 GC 负担。
3) 等于 size,在高并发情况下,数组创建完成之后,size 正在变大的情况下,负面影响与 2 相同。
4) 大于 size,空间浪费,且在 size 处插入 null 值,存在 NPE 隐患
场景:现在有一个int [] arr,希望转换为一个List。
注意:
很容易犯的一个错误就是,使用Arrays.asList()传入int [] 数组,然后用List < Integer>去接受,报错为类型不一致。
Arrays.asList的返回值:
正如上面所看到的,Arrays.asList()会返回一个List。现在我们尝试使用这个list来add(),或者remove()来操作,发现报错了。

看一下Arrays.asList()的源码:

返回了个ArrayList,但是,该ArrayList并不是java.util.ArrayList,而是Arrays的一个内部类。

内部ArrayList的结构:

可以发现它并没有重写add(),remove()两个会改变数据结构的方法,所以当我们直接使用返回的List去add或者remove时,实际上调用的是他的父类AbstractList的add/remove方法:


可以看出这里的实现就是直接抛出了一个异常!
总结:
Arrays.asList()返回的实际上是一个不允许修改其结构的List(注:set(index,val)不属于改变结构的方法)。当前希望对返回的List进行修改结构操作时,按照下面的方式即可:
注意:
看看下面的代码执行结果:

OK,也就是说,返回的List与原数组Integer [] arr2底层使用的是同一份数据。其实前的源码已经看到了这一点:



可以看出,调用Arrays.asList(arr)后,new 内部的ArrayList时直接把数组arr赋值给内部变量E [] a,后面调用get()时,也是直接操作的该内部变量a。
List::subList()会返回一个List:

这个List的实际类型是ArrayList中的一个内部类:


该类是AbstractList的子类,即也是List的实现类,它实现了add/remove方法,故我们可以调用它的add/remove方法。但是:它的add与remove的实现逻辑与ArrayList并不相同,从上面的测试例子以及源码描述可以可看出返回的SubList与父List共用底层的同一个存储数组,所以修改SubList的结构,父List的结构也会发生改变。
另外:
对父List的结构修改后,当再次访问SubList时,会发生fast-fail异常。
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/2199.html