[英]Why does Set.of() throw an IllegalArgumentException if the elements are duplicates?
[英]Set.of(E... elements) - which Set implementation is it using? and what is its relation to 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 使用差异?
Set.of
(和List.of
, Map.of
)使用的具体 class 没有记录。 我们所知道的是返回的 object (a) 实现了接口,并且 (b) 是不可修改的。
这就是我们需要知道的全部。 我们不应该关心幕后使用的特定具体 class。
未知具体 class of
方法的实现者提供了自由。
EnumSet
class。 因此,您永远不应依赖of
/ copyOf
方法所使用的特定具体 class。
您问:
这两者之间的真正区别是什么?
在您的第一个中,我们知道具体的 class。结果集是可修改的。
在您的第二个中,我们不知道具体的 class,也不关心具体的 class。结果集是不可修改的。
代码 | 具体Class | 可修改 |
---|---|---|
新的 HashSet<>() {{ add("a"); 添加(“b”); 添加(“c”); }} | 已知的 | 可修改的 |
Set.of( "a", "b", "c" | 未知 | 不可修改的 |
正如其他人所说,通常最好避免双括号初始化。
如果您想要方便地对可修改集合进行紧凑的文字样式初始化,请结合使用of
方法。 您可以将现有集合传递给构造函数。
Set< String > set =
new HashSet<>(
Set.of( "a", "b", "c" ) // Pass a collection to constructor.
)
;
不保证由Set.of(...)
产生的实现 class。 它可能会根据运行时实现或未来版本而改变。 然而,它的一些特性——主要是不变性——是有保证的。
当您使用“双括号初始化”时,您正在定义一个从指定类型派生的新匿名 class。 所以MySillyTest$1
扩展了HashSet
因为那是你指定的。 请注意,双括号初始化有问题; 我不允许,我也不鼓励其他人使用它。
两者之间的重要区别是Set.of(...)
产生的不变性。 如果您需要一个可变集,那不是一个选择。 但是,如果您可以使用不可变集,它会提供卓越的可读性和性能。
但是,即使您需要一个可变集,也不要将双括号初始化视为Set.of(...)
的替代方案; 只需以常规方式使用HashSet
即可。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.