问题

FromJava 1.6 Collection Framework documentation

不支持任何修改操作的集合(例如添加,删除和清除)称为不可修改。 [...]另外保证Collection对象中的任何更改都不可见的集合称为不可变。

第二个标准让我感到困惑。鉴于第一个集合是不可修改的,并且假设原始集合引用已被丢弃,第二行中引用的更改是什么?它是指集合中保存的元素的变化,即元素的状态?

第二个问题:
对于一个不可变的集合,如何提供额外的guarentees指定?如果集合中的元素状态由一个线程更新,那么状态中的那些更新在持有不可变集合的线程上是不可见的,这对于不变性是否足够?
对于一个不可变的集合,如何提供额外的guarentees指定?


#1 热门回答(137 赞)

不可修改的集合通常是其他集合的只读视图(包装器)。你无法添加,删除或清除它们,但底层集合可能会更改。

不可变的集合根本无法改变 - 它们不包装另一个集合 - 它们有自己的元素。

这是来自guava'sImmutableList的引用

与Collections.unmodifiableList(java.util.List <?extends T>)不同,它是一个可以更改的单独集合的视图,ImmutableList的实例包含自己的私有数据,永远不会更改。

因此,基本上,为了从可变的集合中获取不可变集合,你必须将其元素复制到新集合,并禁止所有操作。


#2 热门回答(78 赞)

不同之处在于你不能引用允许更改的不可变集合。不可修改的集合通过该引用是不可修改的,但是某些其他对象可能指向可以通过其更改的相同数据。

例如

List<String> strings = new ArrayList<String>();
List<String> unmodifiable = Collections.unmodifiableList(strings);
unmodifiable.add("New string"); // will fail at runtime
strings.add("Aha!"); // will succeed
System.out.println(unmodifiable);

#3 热门回答(17 赞)

Collection<String> c1 = new ArrayList<String>();
c1.add("foo");
Collection<String> c2 = Collections.unmodifiableList(c1);

c1ismutable(即.nanunmodifiablenorimmutable)。
c2isunmodifiable:它不能自行更改,但如果稍后我更改c1,那么将在c2中显示更改。

这是因为c2只是一个c1的包装器而不是真正的独立副本。 Guava提供了ImmutableList接口和一些实现。这些工作通过实际创建输入的副本(除非输入是自己的不可变集合)。

关于你的第二个问题:

集合的可变性/不变性不依赖于其中包含的对象的可变性/不变性。修改集合中包含的对象不会将此描述视为"集合的修改"。当然,如果你需要一个不可变的集合,你通常也希望它包含不可变的对象。


原文链接