collections - ArrayList(集合 c)VS HashSet(集合 c)

标签 collections java

在检查 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 使用了参数中集合提供的元素的 COPY (Arrays.copyOf),而 HashSet 使用了 addAll() 方法。

当然,addAll() 方法不会复制元素,只会添加对 HashSet 集合的引用。

我发现这种微妙的差异对于忽略它的调用者来说是“危险的”。

一个人可能期望一个集合具有 SAME 引用,另一个熟悉 ArrayList API 的人可能期望一个来自原始集合的元素的 COPY。

为什么 Sun 没有为这些 Collections 子类提供相同的概念?

最佳答案

ArrayList one used a COPY (Arrays.copyOf) of elements provided by the collection in parameter whereas the HashSet one, use addAll() method.

不,Arrays.copyOf 只复制数组,而不是这个数组指向的对象。对象未被克隆。也就是说,两个构造函数的行为相同 - 它们将包含对与原始集合相同的对象的引用。修改一个集合中的对象会在另一个集合中修改它(因为它是同一个对象)。

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

关于collections - ArrayList(集合 c)VS HashSet(集合 c),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10157218/

相关文章:

java - 线程值非阻塞聚合的数据结构?

java - 我无法使文本文件出现在我的 JTextArea 中

java - 获取 LinkedList 中 map 对象的索引

java - 如何等于 3 ArrayList<String> 并检查此列表中对象的匹配项?

java - CollectionUtils 使用对象元素集合过滤对象集合

java - 迭代列表时删除元素

java - 我如何知道 Android 中 AutoCompleteTextView 的所选项目的位置?

java - 我在使用 HashMap 时抛出 java.util.ConcurrentModificationException

java - 在具有大数据的 DynamoDB 中查询空值或 null 值

java - 更改对话框文本 Android