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

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


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

最佳答案

您没有提到的是“缺陷”。

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

对于TreeSet之类的东西,要考虑一些要点。


普通ImmutableSet保留给定元素的迭代顺序。因此,如果您有TreeSet并使用ImmutableSet.copyOf创建不可变副本,则复制的元素的顺序将与原始顺序相同。
ImmutableSortedSetTreeSet的不变变量,并且像Comparator一样使用元素或TreeSet的自然顺序。


b)您可以创建不使用番石榴而恰好是不变的List的事实,不会改变任何东西。番石榴的不可变集合是专门为不可变而设计的,因此具有各种优势,包括(但不限于):


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

07-24 15:04