【DIY主题讨论:集合转数组】
1)ArrayList.toArray()推荐有参数,还是无参数,为什么? Object[] toArray() :无参方法,返回一个数组,数组包含容器中的所有元素,但是返回时object,会造成类型丢失。 < T > T[] toArray(T[] a) :有参方法,返回一个数组,数组包含容器中的所有元素,返回结果的运行时类型和参数数组a的类型相同,而不是单纯的object。
错误用法:
String[] array4 = (String[]) list.toArray();
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String; 抛出Object无法转化为String异常
正确用法
// 调用无参构造方法,用object数组接收
Object[] array1 = list.toArray();
// 调用有参构造方法,需要先初始化数组
String[] array3 = new String[3];
list.toArray(array3);
使用ArrayList.toArray()的场景:
对比有参数无参数方法,推荐还说使用有参方法,范型的类型擦除对于项目的治理总是不友好的,对于转换后数组的应用也不方便,无参方法我理解为兼容过去没范型的情况。 无参方法返回null的原因是没有参数可以指定返回类型,但个人觉得使用前先创建好数组再赋值不如方法可以负责创建数组并返回结果的好,Arrays.copyOf本身也是可以支持返回数组的。
2)如果有参数,那么参数的数组长度是多少?给出分析的逻辑思考。 参数数组长度为集合长度。 原则一:创建数组是最好给定长度,避免数组扩容对性能的影响。在当前场景下,集合转数组,集合的长度是确定的,所以数组的长度也就是确定的,可以直接给出数组长度。 原因二:当给定数组长度小于集合长度,list.toArray新建一个数组拷贝,给定数组长度大于集合长度,list.toArray可以赋值成功,超出部分数组仍为null。
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);
// 当数组长度大于集合长度,集合结尾处置为null
if (a.length > size) a[size] = null;
return a;
}