在List转数组时,一般会这么写
List<String> list = Arrays.asList("a","b","c");
// 方式1
list.toArray(new String[0]);
// 方式2
list.toArray(new String[list.size()]);
下面是jdk源码(出自ArrayList.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());
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
可以看到当入参数组的长度小于List时,创建了一个新的数组,而如果入参数组大小大于等于List,则直接将List的元素拷贝到入参数组中。
为何不这样实现:
public <T> T[] toArray(Class<T[]> type) {
return Arrays.copyOf(elementData, size, type);
}
代码简单,调用方法时也不用去new一个数组实例?
话说回来,那List转数组的入参中,数组大小到底是设置0
还是list.size()
呢?
2019-12-29 更新一下答案
去
stackoverflow
问了一下国外的大佬们,针对我之前的疑问,有了以下回复(问题链接)答案是可行的,方法本身是可行的,如果觉得有需要,可以提一个增强的请求给
API
设计人员,如果有很多人都想要这个新方法的话,是可以实现的再提到为啥
toArray(T[] a)
是需要传一个泛型的数组,是因为toArray
方法,本身早于泛型,再后续的最早之前的方法就是传入一个Object
数组,类似这样public Object[] toArray(Object[] a)
,所以当Java5泛型出来后,这些方法就被改成泛型的方法了,有一定的历史原因stackoverflow
问题上没有提到,但是大佬在讲解历史的时候有提到点这个,嘤语水平有限,大致意义感觉是设计者参考以前C语言的处理怪癖,注意,这里用到了一个词语quirk
(苦笑)...好吧,总之是大佬可以为所欲为~
看到题主的评论,我发现我之前有一部分想错了,没想到可以
String[].class
这么写,我之前确实从来没有这么写过,更不会想到去传XXObject[].class
,毕竟Java8
里的stream API
里也有个toArray方法,也不是传递XXObject[].class
,而是传递一个数组的构造方法,看了源码,最后也是去根据当前stream
大小创建的新数组。。。因此题主的想法还是很有意思哈,貌似就没有见到
jdk
已有API
传数组class
的,除了Arrays
里有几个方法,那现在为止就是2个问题了以下是原答案,思考有些错误,就灰掉把