在检查ArrayList API时,我注意到一些看起来很奇怪的东西.
实际上,这里是ArrayList构造函数实现,其Collection作为参数传递:
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
Run Code Online (Sandbox Code Playgroud)
这里相当于HashSet类:
public HashSet(Collection<? extends E> c) {
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
Run Code Online (Sandbox Code Playgroud)
因此,我们可以注意到ArrayList使用了参数集合中提供的COPY(Arrays.copyOf)元素,而HashSet则使用了addAll()方法.
当然,addAll()方法不会复制元素,只是添加对HashSet集合的引用.
我发现这个subtil的区别对于忽略它的调用者来说是"危险的".
人们可以期待一个带有SAME引用的集合,另一个读取ArrayList API的人会期望从原始Collection中复制元素.
为什么Sun没有为那些Collections子类提供相同的概念?
ArrayList一个使用了COPY(Arrays.copyOf)中的元素集合提供的元素,而HashSet一个,使用addAll()方法.
不,Arrays.copyOf只复制数组,但不复制此数组指向的对象.没有克隆对象.可以说两个构造函数的行为相同 - 它们将包含与原始集合相同对象的引用.修改一个集合中的对象将在另一个集合中修改它(因为它是同一个对象).
另请注意,Arrays.copyOf()仅在某些情况下使用.
| 归档时间: |
|
| 查看次数: |
948 次 |
| 最近记录: |