簡體   English   中英

Set.of(E... elements) - 它使用的是哪個 Set 實現? 它與 new HashSet<>() 有什么關系?

[英]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 的調試模式下(這個名稱很快就會恢復)我可以看到set1MySillyTest$1的一個實例,但我認為它只是一個HashSet 另一方面, set2ImmutableCollections$SetN的一個實例。 這兩者之間的真正區別是什么? Set.of()使用的是java.util.Set的什么實現? 這兩者之間是否存在性能/內存使用/cpu 使用差異?

不知道,不關心

Set.of (和List.ofMap.of )使用的具體 class 沒有記錄。 我們所知道的是返回的 object (a) 實現了接口,並且 (b) 是不可修改的。

這就是我們需要知道的全部。 我們不應該關心幕后使用的特定具體 class。

未知具體 class of方法的實現者提供了自由。

  • 這些程序員可以根據你的 arguments 的性質自由優化。例如,如果你傳遞的是枚舉 arguments,則可能會在后台使用高度優化的EnumSet class。
  • 這些程序員可以在 Java 的版本之間自由更改他們的具體 class。例如,Java 17 實現可能返回一個具體的 class,而 Java 18 返回另一個。

因此,您永遠不應依賴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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM