问题
如下代码
List<Long> list=new ArrayList<>();
list.add(1L);
list.add(2L);
list.add(3L);
list.add(4L);
List<List<Long>> ll=new ArrayList<>(list);
List<List<Long>> ll_2=new ArrayList<>(Collections.singletonList(list));
ll和ll_2看上去并没有什么不同,甚至他们用的都是同一个构造方法。但是,第一行代码是报错的。因为返回值不匹配。
那么他的返回值是什么呢,大致是这样的
[1, 2, 3, 4]
[[1, 2, 3, 4]]
为什么
为什么会有这样的差距呢?翻看java源码,也就是他们共同的构造方法
/**
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*
* @param c the collection whose elements are to be placed into this list
* @throws NullPointerException if the specified collection is null
*/
public ArrayList(Collection<? extends E> c) {
Object[] a = c.toArray();
if ((size = a.length) != 0) {
if (c.getClass() == ArrayList.class) {
elementData = a;
} else {
elementData = Arrays.copyOf(a, size, Object[].class);
}
} else {
// replace with empty array.
elementData = EMPTY_ELEMENTDATA;
}
}
开始时我确实被共同的参数迷惑住了,都是Collection,为啥就不一样呢?
解决
其实中间有一段需要格外注意的代码
if (c.getClass() == ArrayList.class) {
elementData = a;
} else {
elementData = Arrays.copyOf(a, size, Object[].class);
}
就是这里,如果传入的参数是 ArrayList
类型,则直接赋值。否则的话,是进行了数据的拷贝然后赋值。上面两行代码,一个传入的ArrayList
,一个传入的SingletonList
(一个静态内部类),所以最终的结果也就是不一样的了。