解析List.java的<T> T[] toArray(T[] a)方法及相关数组问题
ArrayList.toArray() 常见问题解答
1. 为什么lst.toArray(new int[0][]);里的数组大小0没影响?
Java集合的toArray(T[] a)方法有明确的处理逻辑:当传入的数组长度小于集合当前的size时,方法会自动创建一个与集合size完全匹配的同类型数组,再把集合元素拷贝进去返回。你传new int[0][]时,0肯定小于集合的实际元素数(只要集合非空),所以这个长度为0的数组只是用来告诉方法要转换的目标数组类型,实际会被丢弃,换成合适大小的新数组。
2. lst.toArray(new int[lst.size()][]);和第一种写法有啥区别?
两者最终都能得到集合转成的数组,但存在两处关键差异:
- 性能细节:Java 8及更早版本中,传长度0的数组会触发两次数组创建(一次是你传的空数组,一次是方法内部新建的合适大小数组);Java 9之后JDK优化了这个逻辑,两种写法性能基本持平。而传
lst.size()大小的数组,方法会直接用这个数组填充元素,不会额外创建数组。 - 边界场景表现:如果在调用
toArray前集合被修改(比如多线程下元素数量变化),传lst.size()的数组可能出现数组长度大于实际元素数的情况,多余位置会被设为null;而传长度0的数组会根据当前实际size创建数组,不会有多余空间。
单线程且集合大小稳定时,两种写法的结果完全一致。
3. lst.toArray(new int[][]);编译报错是因为数组必须指定大小吗?
对,这就是Java语法的硬性要求。创建数组实例时,你必须二选一:要么指定数组的长度(比如new int[3][]),要么用初始化器直接给出数组的元素(比如new int[][]{{1,2}, {3}})。new int[][]这种写法既没说明数组要多大,也没给初始元素,编译器无法确定要创建的数组规格,所以会抛出“Array initializer expected”的错误。
内容的提问来源于stack exchange,提问作者curiousengineer
相关产品推荐
相关产品推荐

