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

卢声远*_* Lu 42 java immutability guava

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!
Run Code Online (Sandbox Code Playgroud)

谁能解释一下呢?

Jon*_*eet 86

考虑一下:

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
Run Code Online (Sandbox Code Playgroud)

换句话说,ImmutableSet尽管它是由可能改变而构建的集合,但它是不可变的 - 因为它创建了一个副本.Collections.unmodifiableSet防止直接更改返回的集合,但它仍然是可能更改的后备集的视图.

请注意,如果您开始更改任何集合引用的对象的内容,则无论如何都会关闭所有投注.不要那样做.实际上,首先使用可变元素类型创建集合并不是一个好主意.(使用可变密钥类型的Ditto映射.)

  • @卢声远盛源路:应该是`ImmutableSet.copyOf` - 否则你试图建立一套集...... (5认同)

Col*_*inD 19

除了Jon提到的行为差异之外,创造者ImmutableSetSet创造者之间的重要区别在于Collections.unmodifiableSetImmutableSet是一种类型.您可以传递一个,并通过使用ImmutableSet而不是Set整个代码使组件保持不变.有了Collections.unmodifiableSet,返回的类型只是Set...所以很明显该集合在创建它的位置是不可修改的,除非你在传递的地方添加Javadoc,Set说"这个集合是不可修改的".


Eti*_*veu 10

Kevin Bourrillion(Guava首席开发人员)在此演示文稿中比较了不可变/不可修改的集合.虽然演示文稿已有两年历史,并专注于"Google Collections"(现在是Guava的子部分),但这是一个非常有趣的演示.API可能已经发生变化(Google Collections API当时处于测试阶段),但Google Collections/Guava背后的概念仍然有效.

您可能也对这个其他SO问题感兴趣(google的ImmutableList和Collections.unmodifiableList()之间有什么区别).