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

发布于 2024-10-31 07:20:08 字数 528 浏览 2 评论 0原文

ImmutableSet 的 JavaDoc 说:

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

但是 ImmutableSet 仍然存储元素的引用,我无法弄清楚与 Collections.unmodifyingSet() 的区别。示例:

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

谁能解释一下吗?

JavaDoc of ImmutableSet says:

Unlike Collections.unmodifiableSet, which is a view of a separate collection that can still change, an instance of this class contains its own private data and will never change. This class is convenient for public static final sets ("constant sets") and also lets you easily make a "defensive copy" of a set provided to your class by a caller.

But the ImmutableSet still stores reference of elements, I couldn't figure out the difference to Collections.unmodifiableSet(). Sample:

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

Could anyone explain it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

北恋 2024-11-07 07:20:08

考虑一下:

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.unmodifyingSet 防止返回的集合被直接更改,但它仍然是可能更改的支持集的视图。

请注意,如果您开始更改任何集合引用的对象的内容,那么无论如何,所有的赌注都会被取消。不要那样做。事实上,首先使用可变元素类型创建集合并不是一个好主意。 (同上,使用可变键类型进行映射。)

Consider this:

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

In other words, ImmutableSet is immutable despite whatever collection it's built from potentially changing - because it creates a copy. Collections.unmodifiableSet prevents the returned collection from being directly changed, but it's still a view on a potentially-changing backing set.

Note that if you start changing the contents of the objects referred to by any set, all bets are off anyway. Don't do that. Indeed, it's rarely a good idea to create a set using a mutable element type in the first place. (Ditto maps using a mutable key type.)

你丑哭了我 2024-11-07 07:20:08

除了 Jon 提到的行为差异之外,ImmutableSetCollections.unmodifyingSet 创建的 Set 之间的一个重要区别是 ImmutableSet code> 是一个类型。您可以通过在整个代码中使用 ImmutableSet 而不是 Set 来传递一个集合,并清楚地表明该集合是不可变的。使用Collections.unmodifyingSet,返回的类型只是Set...所以很明显,集合在创建时是不可修改的,除非您在任何地方添加Javadoc传递 Set 说“这个集合是不可修改的”。

Besides the behavioral difference that Jon mentions, an important difference between ImmutableSet and the Set created by Collections.unmodifiableSet is that ImmutableSet is a type. You can pass one around and have it remain clear that the set is immutable by using ImmutableSet rather than Set throughout the code. With Collections.unmodifiableSet, the returned type is just Set... so it's only clear that the set is unmodifiable at the point where it is created unless you add Javadoc everywhere you pass that Set saying "this set is unmodifiable".

南…巷孤猫 2024-11-07 07:20:08

Kevin Bourrillion (Guava lead developer) compares immutable / unmodifiable collections in this presentation. While the presentation is two years old, and focuses on "Google Collections" (which is now a subpart of Guava), this is a very interesting presentation. The API may have changed here and there (the Google Collections API was in Beta at the time), but the concepts behind Google Collections / Guava are still valid.

You might also be interested in this other SO question ( What is the difference between google's ImmutableList and Collections.unmodifiableList() ).

月朦胧 2024-11-07 07:20:08

其他答案中未说明的两者之间的区别是 ImmutableSet 不允许 null 值,如 Javadoc

高性能、不可变的集合,具有可靠的、用户指定的迭代顺序。不允许空元素。

(同样的限制适用于所有 Guava 不可变集合中的值。)

例如:

ImmutableSet.of(null);
ImmutableSet.builder().add("Hi").add(null); // Fails in the Builder.
ImmutableSet.copyOf(Arrays.asList("Hi", null));

所有这些都在运行时失败。相比之下:

Collections.unmodifiableSet(new HashSet<>(Arrays.asList("Hi", null)));

这很好。

A difference between the two not stated in other answers is that ImmutableSet does not permit null values, as described in the Javadoc

A high-performance, immutable Set with reliable, user-specified iteration order. Does not permit null elements.

(The same restriction applies to values in all Guava immutable collections.)

For example:

ImmutableSet.of(null);
ImmutableSet.builder().add("Hi").add(null); // Fails in the Builder.
ImmutableSet.copyOf(Arrays.asList("Hi", null));

All of these fail at runtime. In contrast:

Collections.unmodifiableSet(new HashSet<>(Arrays.asList("Hi", null)));

This is fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文