不可变的番石榴收藏品的缺陷?

时间:2011-04-11 02:46:26

标签: java collections immutability guava unmodifiable

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

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));

您对Immutable系列的理解是什么?谢谢!

3 个答案:

答案 0 :(得分:21)

你所提到的都不是“缺陷”。

a) ImmutableList不再是链接列表根本不重要。链表与基于数组的列表的唯一优点包括添加和删除元素(主要删除)。您不能添加到不可变列表或从中删除,因此基于数组的快速随机访问以及内存效率更可取。

对于类似TreeSet的内容,需要考虑很多要点。

  1. 普通ImmutableSet保留其给定元素的迭代顺序。因此,如果您有TreeSet并使用ImmutableSet.copyOf创建不可变副本,则复制的元素的排序方式与原始元素相同。
  2. ImmutableSortedSetTreeSet的不可变等价物,使用元素的自然排序或Comparator TreeSet
  3. b)您可以在不使用Guava的情况下创建恰好是不可变的List并不会改变任何内容。 Guava的不可变集合在具体的设计中考虑了不变性,因此具有各种优势,包括(但不限于):

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

答案 1 :(得分:4)

  

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

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

答案 2 :(得分:3)

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

虽然演示文稿已有两年历史,并专注于“Google Collections”(现在是Guava的子部分),但这是一个非常有趣的演示文稿。自演示文稿以来,API可能稍有变化,因为Google Collections API当时处于测试阶段,但大多数概念保持不变。