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

时间:2010-02-02 16:39:05

标签: java collections comparison guava

来自ImmutableList javadocs:

  

不同于   Collections.unmodifiableList(java.util.List中)   这是一个单独的视图   仍然可以改变的集合,   ImmutableList的实例包含它   拥有私人数据,永远不会   更改。 ImmutableList很方便   用于公共静态最终列表   (“常量列表”)也可以让你   轻松制作一个“防御性副本”   列表由您提供给您的班级   呼叫者。

这是否意味着:

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

5 个答案:

答案 0 :(得分:53)

不,不变性仅适用于Collection中对象的数量和引用,并不能解决您放入Collection中的对象的可变性。

不可变列表比标准JDK Collections.unmodifiableList获得的是通过使用ImmutableList可以保证引用的对象,它们的顺序和列表大小不能从任何源更改。使用Collections.unmodifiableList,如果其他内容具有对基础列表的引用,即使您引用了不可修改的列表,该代码也可以修改列表。

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

答案 1 :(得分:17)

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

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

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

答案 2 :(得分:6)

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

答案 3 :(得分:3)

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

答案 4 :(得分:0)

您可能还想看看this question(番石榴的Collections.unmodifiableSet()ImmutableSet之间有什么区别。)