谷歌的ImmutableList和Collections.unmodifiableList()有什么区别?

来自ImmutableList javadocs:

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

这是否意味着:

  1. 如果我有Dimension对象的ImmutableList(例如),那么我不能改变它的任何维对象?
  2. 如果我有维度对象的Collections.unmodifiableList(列表),那么我不能只添加或删除任何对象,但我可以改变它们(例如调用setDimension(宽度,高度)方法)?

不,不变性仅适用于集合中对象的数量和引用,并且不涉及放入集合中的对象的可变性。

什么不可变列表获得的标准JDK Collections.unmodifiableList是通过使用ImmutableList你保证引用的对象,它们的顺序和列表的大小不能改变任何来源。 使用Collections.unmodifiableList如果别的东西有一个对基础列表的引用,该代码可以修改列表,即使你有一个不可修改的列表的引用。

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

使用Collections.unmodifiableList创build一个你的List的包装。 如果底层列表发生了变化,那么您的不可修改列表视图也会发生变化。

正如文档所述,Google的代码创build了一个副本。 这是一个更昂贵的计算,消耗更多的内存,但如果有人改变了原来的列表,它不能影响ImmutableList。

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

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

  1. 不,包含的单个对象仍然可以修改。 集合实际上只存储包含对象的引用 ,而不是每个对象的完整副本。
  2. 您可以通过修改您调用Collections.unmodifiableList(list)的父集合来修改列表。 但是,是的,你可以使用setDimension来改变存储的列表元素。

你可能也想看看这个问题 (什么是不同的Collections.unmodifiableSet()和番石榴的ImmutableSet )。