Guava的Collections.unmodifiableSet()和ImmutableSet有什么区别?


问题内容

JavaDoc ImmutableSet说:

Collections.unmodifiableSet,它是仍然可以更改的单独集合的视图不同,此类的实例包含其自己的私有数据,并且永远不会更改。此类对于公共静态最终集(“常量集”)很方便,并且还使您可以轻松地对调用者提供给您的类的集进行“防御性复制”。

但是ImmutableSet仍然存储元素的引用,我无法找出与的区别Collections.unmodifiableSet()。样品:

StringBuffer s=new StringBuffer("a");
ImmutableSet<StringBuffer> set= ImmutableSet.of(s);
s.append("b");//s is "ab", s is still changed here!

有人可以解释吗?


问题答案:

考虑一下:

Set<String> x = new HashSet<String>();
x.add("foo");

ImmutableSet<String> guava = ImmutableSet.copyOf(x);
Set<String> builtIn = Collections.unmodifiableSet(x);

x.add("bar");
System.out.println(guava.size()); // Prints 1
System.out.println(builtIn.size()); // Prints 2

换句话说,ImmutableSet尽管它是通过潜在的更改构建的,但它是不可变的-
因为它创建了副本。Collections.unmodifiableSet防止 返回的 集合被直接更改,但这仍然是一个可能更改的支持集的视图。

请注意,如果您开始更改任何集合所 引用 的对象的内容,则所有选择都将关闭。不要那样做
确实,首先使用可变元素类型创建集合并不是一个好主意。(Ditto使用可变键类型进行映射。)