我不确定我理解的不可变集合的缺陷是否正确,所以我在这个答案中列出它们。希望有人在这里纠正我。
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系列的理解是什么?谢谢!
答案 0 :(得分:21)
你所提到的都不是“缺陷”。
a) ImmutableList
不再是链接列表根本不重要。链表与基于数组的列表的唯一优点包括添加和删除元素(主要删除)。您不能添加到不可变列表或从中删除,因此基于数组的快速随机访问以及内存效率更可取。
对于类似TreeSet
的内容,需要考虑很多要点。
ImmutableSet
保留其给定元素的迭代顺序。因此,如果您有TreeSet
并使用ImmutableSet.copyOf
创建不可变副本,则复制的元素的排序方式与原始元素相同。ImmutableSortedSet
是TreeSet
的不可变等价物,使用元素的自然排序或Comparator
TreeSet
。 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当时处于测试阶段,但大多数概念保持不变。