[英]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.