57

来自 ImmutableList javadocs:

与 Collections.unmodifiableList(java.util.List) 不同,后者是仍然可以更改的单独集合的视图,ImmutableList 的实例包含自己的私有数据并且永远不会更改。ImmutableList 对于公共静态最终列表(“常量列表”)很方便,还可以让您轻松地制作由调用者提供给您的类的列表的“防御性副本”。

是不是意味着:

  1. 如果我有 Dimension 对象的 ImmutableList(例如),那么我不能更改其中的任何 Dimension 对象?
  2. 如果我有 Dimension 对象的 Collections.unmodifiableList (列表),那么我不仅可以添加或删除任何对象,而且可以更改它们(例如调用 setDimension(width, height) 方法)?
4

5 回答 5

57

不,不变性仅适用CollectionCollection.

与标准 JDK 相比,Immutable list 获得的好处Collections.unmodifiableList是,通过使用ImmutableList可以保证引用的对象、它们的顺序和列表的大小不能从任何来源改变。如果其他东西引用了Collections.unmodifiableList基础列表,即使您引用了不可修改的列表,该代码也可以修改列表。

但是,如果您想要真正的不变性,则必须用不可变对象填充列表。

于 2010-02-02T16:43:44.493 回答
19

使用Collections.unmodifiableList在您的列表周围创建一个包装器。如果基础列表发生变化,您的 unmodifiableList 视图也会发生变化。

正如文档所说,谷歌的代码创建了一个副本。这是一个更昂贵的计算并且消耗更多的内存,但是如果有人更改了原始列表,它不会影响 ImmutableList。

这些都不会阻止您更改列表中的对象,或者它的字段,或字段的字段等。

于 2010-02-02T16:45:07.620 回答
7

ImmutableList类似于Collections.unmodifiableList( new ArrayList( list ) )。请注意,新创建ArrayList分配给字段或变量。

于 2010-02-02T16:50:01.277 回答
3
  1. 不,包含的单个对象仍然可以修改。集合实际上只是存储对包含对象的引用,而不是每个对象的完整副本。
  2. 您可以通过修改您在其上调用 Collections.unmodifiableList(list) 的父 Collection 来修改列表。但是,是的,您可以使用 setDimension 来更改存储的列表元素。
于 2010-02-02T16:45:45.317 回答
0

您可能还想看看这个问题Collections.unmodifiableSet()(Guava和Guava有什么区别ImmutableSet)。

于 2011-06-28T09:51:46.763 回答