google 的 ImmutableList 和 Collections.unmodifiableList() 有啥区别?
Posted
技术标签:
【中文标题】google 的 ImmutableList 和 Collections.unmodifiableList() 有啥区别?【英文标题】:What is the difference between google's ImmutableList and Collections.unmodifiableList ()?google 的 ImmutableList 和 Collections.unmodifiableList() 有什么区别? 【发布时间】:2011-01-12 05:58:52 【问题描述】:来自 ImmutableList javadocs:
不像 Collections.unmodifiableList(java.util.List), 这是一个单独的视图 仍然可以改变的收藏,一个 ImmutableList 的实例包含其 拥有私人数据,永远不会 改变。 ImmutableList 很方便 用于公共静态最终列表 (“常量列表”),还可以让您 轻松制作一个“防御性副本” 由 a 提供给您的班级的列表 来电者。
是不是意味着:
-
如果我有 Dimension 对象的 ImmutableList(例如),那么我不能更改其中的任何 Dimension 对象?
如果我有 Dimension 对象的 Collections.unmodifiableList(列表),那么我不仅可以添加或删除任何对象,还可以更改它们(例如调用 setDimension(width, height) 方法)?
【问题讨论】:
您可能还想看看What's the difference between Collections.unmodifiableSet() and ImmutableSet of Guava 【参考方案1】:不,不变性只适用于Collection
中对象的数量和引用,不解决您放入Collection
中的对象的可变性。
与标准 JDK Collections.unmodifiableList
相比,不可变列表的优势在于,通过使用 ImmutableList
,您可以保证引用的对象、它们的顺序和列表的大小不会因任何来源而改变。使用Collections.unmodifiableList
,如果其他内容引用了基础列表,即使您引用了不可修改的列表,该代码也可以修改列表。
但是,如果您想要真正的不可变性,则必须用不可变对象填充列表。
【讨论】:
@Vuntic,如果类是真正不可变的,它的字段被声明为 final,反射不能改变它。 @Yishai,反射可以修改final字段。试试看。 @Vuntic,使用 setAccessible?这取决于安全经理;)。 @Vuntic,当我尝试修改最终字段而不设置 setAccessable 时出现异常。你在想什么?顺便说一句,这个问题也没有提到反射;) @Yishai 我知道我在这次谈话中迟到了 7 年......但是为了公开记录,您首先使用反射删除 final 修饰符来修改 final 字段。但它只适用于对象,不适用于基元。【参考方案2】:使用Collections.unmodifiableList
在您的列表周围创建一个包装器。如果基础列表发生变化,您的 unmodifiableList 视图也会发生变化。
正如文档所述,Google 的代码会创建一个副本。这是一个更昂贵的计算并且消耗更多的内存,但是如果有人更改了原始列表,它不会影响 ImmutableList。
这些都不会阻止您更改列表中的对象,或者它的字段,或字段的字段等。
【讨论】:
“正如文档所述,Google 的代码会创建一个副本。”它可能创建一个副本。如果原始数据结构也是不可变的数据结构,它实际上可能能够重用它。所以如果你广泛使用ImmutableList
,你会经常遇到这种情况,最终不必复制太多。【参考方案3】:
ImmutableList
类似于 Collections.unmodifiableList( new ArrayList( list ) )
。请注意,新创建的ArrayList
未分配给字段或变量。
【讨论】:
【参考方案4】:-
不,包含的单个对象仍然可以修改。集合实际上只是存储对所包含对象的引用,而不是每个对象的完整副本。
您可以通过修改您在其上调用 Collections.unmodifiableList(list) 的父 Collection 来修改列表。但是,是的,您可以使用 setDimension 更改存储的列表元素。
【讨论】:
【参考方案5】:您可能还想看看this question(Guava 的Collections.unmodifiableSet()
和ImmutableSet
有什么区别)。
【讨论】:
以上是关于google 的 ImmutableList 和 Collections.unmodifiableList() 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章