簡體   English   中英

如何在 Map.of 工廠中保留插入順序?

[英]How to preserve order of insertion in Map.of factory?

Java 9 提供Map.of()功能來輕松創建具有固定值的地圖。

問題:我想創建一個保留插入順序的地圖,如LinkedHashMap 那家工廠可以嗎? 至少map.of()不保留順序...

確實沒有像LinkedHashMap::of這樣的工廠方法,而且Map本身沒有訂單,所以我看到的唯一方法是在你真的需要時構建一個LinkedHashMap

順便說一句,來自JEP 本身

具體集合類(例如,ArrayList、HashSet)上的靜態工廠方法已從該提案中刪除...

還有一個問題,就是類上的靜態方法是由子類繼承的。 假設要添加一個靜態工廠方法 HashMap.of()。 由於 LinkedHashMap 是 HashMap 的子類,因此應用程序代碼可以調用 LinkedHashMap.of()。 這最終會調用 HashMap.of(),這完全不是人們所期望的!

這里的重點是static方法是繼承的,但不可覆蓋,因此如果將這樣的方法添加到HashMap中,它可能不會在LinkedHashMap中被覆蓋。

如果您可以使用guava ,您可以使用ImmutableMap記錄為:

一個不可變的、基於哈希的 Map 具有可靠的用戶指定的迭代順序......

正如Map的 Java apidoc 中所記錄的那樣(強調我的):

不可修改的地圖

Map.ofMap.ofEntriesMap.copyOf靜態工廠方法提供了一種方便的方式來創建不可修改的地圖。 這些方法創建的 Map 實例具有以下特點:

  • ...
  • 映射的迭代順序未指定,可能會發生變化。
  • ...

不幸的是,Java API 中沒有創建LinkedHashMap的等效便捷方法。 如果您想要一個一致的迭代順序,那么您將需要手動創建一個LinkedHashMap並填充它(並且 - 如果需要 - 使用Collections.unmodifiableMap包裝它)。

考慮創建自己的便捷方法,該方法與Map.of等效,但具有一致的迭代順序(或查找已經提供此功能的現有庫)。

因為在 JDK 中似乎沒有任何方法可以做你想做的事情,你必須自己實現它或使用現有的庫。 創建這樣的輔助方法並不難:

public static <K, V> LinkedHashMap<K, V> of(Collection<Entry<? extends K, ? extends V>> entries) {
  final LinkedHashMap<K, V> map = new LinkedHashMap<>();
  entries.forEach(entry -> map.put(entry.getKey(), entry.getValue()));
  return map;
}

然后你可以像這樣使用它:

of(List.of(Map.entry("Hello", "World"), Map.entry("Goodnight", "Moon")));

該解決方案優於 JDK 中的 Map.of,即鍵值對作為條目對提供,而不僅僅是通過參數索引作為丟失對提供。

您還可以通過以下方式使用 vavr.io:

Map<String, String> mapPreservingInsertionOrder = io.vavr.collection.LinkedHashMap.of("key1", "val1", "key2", "val2").toJavaMap();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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