ArrayList(Collection c)VS HashSet(Collection c)

Mik*_*378 2 java collections

在检查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子类提供相同的概念?

Tom*_*icz 8

ArrayList一个使用了COPY(Arrays.copyOf)中的元素集合提供的元素,而HashSet一个,使用addAll()方法.

不,Arrays.copyOf只复制数组,但不复制此数组指向的对象.没有克隆对象.可以说两个构造函数的行为相同 - 它们将包含与原始集合相同对象的引用.修改一个集合中的对象将在另一个集合中修改它(因为它是同一个对象).

另请注意,Arrays.copyOf()仅在某些情况下使用.