【问题标题】:Defects of Immutable collections of Guava?Guava 的不可变集合的缺陷?
【发布时间】:2011-08-02 17:52:48
【问题描述】:

我不确定我理解的不可变集合的缺陷是否正确,所以我在这个答案中列出了它们。希望有人在这里纠正我。

a):与 Collections.unmodifiableXXX() 相比,ImmutableXXX.copyOf() 失去了源集合功能。例如,当将linkedList 放入ImmutableList.copyOf() 时,ImmutableList 不再链接。与基于树的集合相同。

b):人们认为 Collections.unmodifiableXXX 只是使用了与源集合相同的引用,所以一旦源集合改变,Collections.unmodifiableXXX 也随之改变。但我的解决方案是将源集合包装到传递给 ImmutableXXX.copyOf() 的临时集合中。见以下代码:

List<String> l = new ArrayList<String>();
List<String>  unmodifiableList = Collections.unmodifiableList(l);
ImmutableList<String> immutableList= ImmutableList.copyOf(l);
l.add("a");//unmodifiableList is also added "a", immutableList not.

/*My solution as follows:
So unmodifiableList2 is also immutable as ImmutableList.copyOf(l) does*/
List<String> unmodifiableList2= Collections.unmodifiableList(new ArrayList(l));

您对不可变集合的理解是什么?谢谢!

【问题讨论】:

    标签: java collections immutability guava unmodifiable


    【解决方案1】:

    你提到的任何东西都不是“缺陷”。

    a) ImmutableList 不再是链表并不重要。与基于数组的列表相比,链表的唯一优势在于添加和删除元素(主要是删除)。您无法在不可变列表中添加或删除,因此基于数组的随机访问速度快,内存效率高。

    对于TreeSet 之类的内容,需要考虑一些要点。

    1. 普通的ImmutableSet 会保留给定元素的迭代顺序。因此,如果您有 TreeSet 并使用 ImmutableSet.copyOf 创建不可变副本,则复制的元素将按照与原始元素相同的顺序排列。
    2. ImmutableSortedSetTreeSet 的不可变等价物,它使用元素的自然顺序或 Comparator,就像 TreeSet 一样。

    b) 您可以在不使用 Guava 的情况下创建恰好是不可变的 List,这一事实不会改变任何事情。 Guava 的不可变集合在设计时专门考虑了不可变性,因此它们具有各种优势,包括(但不限于):

    • 正如我在对您上一个问题的回答中提到的那样,它们的不变性在类型级别得到保证。当你的方法返回ImmutableSet 类型的东西时,调用者知道 设置不能改变它们。如果它只返回Set,则不是这样。
    • 内存优化,包括用于空情况的单例和用于 1 元素情况的特殊类。
    • 如果输入已经是同一类型的不可变实例,ImmutableSet.copyOf 等实际上不会复制任何内容。
    • 可轻松创建不可变集合的方法/构建器。

    【讨论】:

    • 有见地的回答。谢谢!
    【解决方案2】:

    为什么我们需要不可变集合

    • 它极大地简化了并发编程。思考 关于它,为什么编写正确的多线程编程很难?因为 很难同步线程对给定资源(在本例中为列表)的访问。

    【讨论】:

      【解决方案3】:

      ColinD 和 Amir 直接回答了您的具体问题,但您可能还想查看 GTUG - Using the Google Collections Library for Java (1 of 2) - Kevin Bourrillion(Guava 的首席开发人员)关于不可变集合的演示,其中他解释了不可变集合的所有优点。

      虽然该演示文稿已有两年时间,并且重点关注“Google 收藏”(现在是 Guava 的一个子部分),但这是一个非常有趣的演示文稿。该 API 自演示以来可能已经发生了一些变化,因为当时 Google Collections API 处于测试阶段,但大多数概念保持不变。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-22
        • 2015-06-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多