2010-02-02 53 views
43

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

不像 Collections.unmodifiableList(java.util.List中), 这是一个单独 集合,仍然可以改变的观点,ImmutableList的 实例包含其 自己的私人数据并不会 更改。 ImmutableList是公共静态最终名单 (“常数表”)方便 ,也可以让你 容易被 呼叫者提供让你的类 列表的“防御性复制”。

这是否意味着:

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

您可能还想看看[Guava的Collections.unmodifiableSet()和ImmutableSet](http://stackoverflow.com/q/5611324/977087) – Crowie 2015-04-22 15:35:06

回答

52

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

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

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

+0

之间的区别是什么?当然,反射... – naiad 2011-03-02 14:57:23

+0

@Vuntic,如果类是真正不可变的,它的字段被声明为final,并且反射不能改变它。 – Yishai 2011-03-03 14:37:20

+1

@易海,反思*可以*修改最终字段。尝试一下。 – naiad 2011-03-06 06:56:22

14

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

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

这些都不可以防止你在列表中更改对象,或者它的领域,或字段的字段等

+2

“正如文档所述,Google的代码创建了一个副本。”它*可能*创建一个副本。如果原始文件也是不可变的数据结构,它实际上可以重用它。所以如果你广泛使用'ImmutableList',你会经常碰到这种情况,最终不会复制太多。 – 2014-03-18 04:58:49

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

ImmutableListCollections.unmodifiableList(new ArrayList(list))相似。请注意,新创建的ArrayList而不是分配给一个字段或变量。

0

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