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() 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

Dubbo 与 ImmutableList冲突解决

SpringBoot整合JOOQ例子

函数式接口的简单使用

Filecoin java 离线生成地址

Guava学习二(集合并发文件)

给我半首歌的时间,给你说明白Immutable List