Set.of(E... elements) - 它使用哪个 Set 实现?它与 new HashSet<>() 有何关系?
我想问 -
Set<CurrencyType> set1 = new HashSet<>() {{
add("a");
add("b");
add("c");
}}
和
Set<CurrencyType> set2 = Set.of(
"a",
"b",
"c"
)
在名为 MySillyTest
的 @Test 的调试模式下有什么区别(这个名称很快就会回来)我可以看到 set1
是一个MySillyTest$1
的实例,但我假设它只是一个 HashSet
。另一方面,set2
是 ImmutableCollections$SetN
的实例。这两者之间真正的区别是什么? Set.of()
使用的是 java.util.Set
的什么实现?这两者之间有性能/内存使用/CPU 使用差异吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不知道,不关心
Set.of
(和List.of
,Map.of
) 未记录。我们所知道的是返回的对象(a)实现了接口,并且(b)是不可修改的。这就是我们需要知道的全部。我们不应该关心幕后使用的特定具体类。
未知具体类为
of
方法的实现者提供了自由。EnumSet
类可能在幕后使用。因此,您不应该永远依赖于/
copyOf
方法。你问:
在你的第一个中,我们知道具体的类。并且结果集是可以修改的。
在你的第二个中,我们不知道具体的类,也不关心具体的类。并且结果集是不可修改的。
避免双括号
正如其他人所说,通常是 最好避免双括号初始化
如果您想要方便地对可修改集合进行紧凑的文字样式初始化,请与
of
方法结合使用,您可以将现有集合传递给。 “但是我确实关心......”
如果您确实关心实现的具体细节,那么您不应该使用
Set.of
。如上所述,因此您不应依赖Set.of
的特定实现。当您的项目有特定需求时,您应该明确选择满足这些需求的特定实现。捆绑实现,从第三方库获取一个,例如 Eclipse Collections 或 Google Guava,或编写您自己的。
提示:您可以利用
Set.of
的便捷语法,将其结果传递给所选实现的构造函数。请参阅上面的代码示例:Don’t know, don’t care
The concrete class used by
Set.of
(andList.of
,Map.of
) is not documented. All we know is that the object returned (a) implements the interface, and (b) is unmodifiable.That is all we need to know. We should not care about the particular concrete class used under the covers.
Being of unknown concrete class gives freedom to the implementors of the
of
methods.EnumSet
class might be used behind the scenes.So you should never depend on a particular concrete class being utilized by the
of
/copyOf
methods.You asked:
In your first one, we know the concrete class. And the resulting set is modifiable.
In your second one, we do not know the concrete class, nor do we care about the concrete class. And the resulting set is unmodifiable.
Avoid double-brace
As others said, it’s generally best to avoid double-brace initialization.
If you want the convenience of compact literals-style initialization of your modifiable collection, combine with the
of
methods. You can pass an existing collection to the constructor.“But I do care …”
If you do care about the specific details of the implementation, then you should not use
Set.of
. The implementation details may vary as discussed above, so you should not rely on a specific implementation withSet.of
.When your project has specific needs, you should explicitly choose a particular implementation that meets those needs. You can choose one of the bundled implementations, obtain one from a third-party library such as Eclipse Collections or Google Guava, or write your own.
Tip: You can leverage the convenient syntax of
Set.of
by passing its result to the constructor of your chosen implementation. See the code example above:不保证
Set.of(...)
生成的实现类。它可能会根据运行时实现或未来版本而改变。然而,它的一些特性——主要是不变性——是得到保证的。当您使用“双括号初始化”时,您正在定义一个从指定类型派生的新匿名类。因此,
MySillyTest$1
扩展了HashSet
,因为这是您指定的。请注意,双括号初始化有问题;我不允许它,并且我不鼓励其他人使用它。两者之间的重要区别是由
Set.of(...)
产生的不变性。如果您需要一个可变集,那么这不是一个选择。但如果您可以使用不可变集,它就会提供卓越的可读性和性能。但是,即使您需要可变集,也不要将双括号初始化视为 Set.of(...) 的替代方案;只需按照常规方式使用
HashSet
即可。The implementation class resulting from
Set.of(...)
is not guaranteed. It could change depending on the runtime implementation or in future versions. However, some of its characteristics—chiefly immutability—are guaranteed.When you use "double-brace initialization", you are defining a new anonymous class that derives from the specified type. So
MySillyTest$1
extendsHashSet
because that's what you specified. Note that double-brace initialization has problems; I don't allow it, and I discourage others from using it.The important difference between the two is the immutability resulting from
Set.of(...)
. If you need a mutable set, it's not an option. But if you can use an immutable set, it provides superior readability and performance.Even if you need a mutable set, however, don't look at double-brace initialization as an alternative to
Set.of(...)
; just use aHashSet
in the conventional way.