不可变的番石榴collections品的缺陷?

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

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

b):人们认为Collections.unmodifiableXXX只使用相同的源集合引用,因此一旦源集合发生更改,Collections.unmodifiableXXX也会更改。 但我的解决方案是将源集合包装到临时集合中,该集合传递给ImmutableXXX.copyOf()。 见下面的代码:

List l = new ArrayList(); List unmodifiableList = Collections.unmodifiableList(l); ImmutableList 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 unmodifiableList2= Collections.unmodifiableList(new ArrayList(l)); 

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

你提到的没有什么是“缺陷”。

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

对于像TreeSet这样的东西,有很多要点需要考虑。

  1. 正常的ImmutableSet保留了它给定的元素的迭代顺序。 因此,如果您有一个TreeSet并使用ImmutableSet.copyOf来创建不可变副本,则复制的元素将按原始顺序排序。
  2. ImmutableSortedSetTreeSet的不可变等价物,它使用元素的自然排序或者像TreeSet一样使用Comparator

b)你可以在不使用Guava的情况下创建恰好是不可变的List这一事实并没有改变任何东西。 Guava的不可变集合是专门针对不变性而设计的,因此具有各种优势,包括(但不限于):

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

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

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

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

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