在检查 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);
}
这里相当于 HashSet 类:
public HashSet(Collection<? extends E> c) {
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
因此,我们可以注意到 ArrayList 使用了由集合 in 参数提供的元素的 COPY (Arrays.copyOf),而 HashSet 使用 addAll() 方法。
当然,addAll() 方法不会复制元素,而只是添加对 HashSet 集合的引用。
对于忽略它的呼叫者,我发现这种细微的差异是“危险的”。
一个人可能会期望一个具有相同引用的集合,另一个阅读 ArrayList API 的人会期望一个原始集合中元素的副本。
为什么 Sun 没有为这些 Collections 子类提供相同的概念?