Map.ofEntries() 和 Map.of() 之間的區別
一、簡介
Java 8 引入了Map.of()
方法,這使得創建不可變映射變得更加容易。 Java 9 獲得了Map.ofEntries()
方法,其功能略有不同。
在本教程中,我們將仔細研究不可變映射的這兩個靜態工廠方法,並解釋哪一個適用於哪個目的。
Map.of()
Map.of()
方法將指定數量的鍵值對作為參數,並返回包含每個鍵值對的不可變映射。參數中對的順序對應於將它們添加到地圖的順序。如果我們嘗試添加具有重複鍵的鍵值對,它會拋出IllegalArgumentException
。如果我們嘗試添加null
鍵或值,它將拋出NullPointerException
。
作為重載的static
工廠方法實現,第一個讓我們創建一個空映射:
static <K, V> Map<K, V> of() {
return (Map<K,V>) ImmutableCollections.EMPTY_MAP;
}
讓我們看看用法:
Map<Long, String> map = Map.of();
在Map<K, V>
的接口中還定義了一個方法,它採用單個鍵和值:
static <K, V> Map<K, V> of(K k1, V v1) {
return new ImmutableCollections.Map1<>(k1, v1);
}
讓我們稱之為:
Map<Long, String> map = Map.of(1L, "value1");
這些工廠方法被重載了九次,最多接受十個鍵和十個值,正如我們在OpenJDK 17中所見:
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10) {
return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10);
}
儘管這些方法非常有用,但創建更多它們將是一團糟。此外,我們不能使用Map.of()
方法從現有鍵和值創建映射,因為此方法只接受未定義的鍵值對作為參數。這就是Map.ofEntries()
方法的用武之地。
Map.ofEntries()
Map.ofEntries()
方法將未指定數量的Map.Entry<K, V>
對像作為參數,並返回一個不可變映射。同樣,參數中對的順序與它們添加到地圖的順序相同。如果我們嘗試添加具有重複鍵的鍵值對,它會拋出IllegalArgumentException
。
讓我們看看根據OpenJDK 17的靜態工廠方法實現:
static <K, V> Map<K, V> ofEntries(Entry<? extends K, ? extends V>... entries) {
if (entries.length == 0) { // implicit null check of entries array
var map = (Map<K,V>) ImmutableCollections.EMPTY_MAP;
return map;
} else if (entries.length == 1) {
// implicit null check of the array slot
return new ImmutableCollections.Map1<>(entries[0].getKey(), entries[0].getValue());
} else {
Object[] kva = new Object[entries.length << 1];
int a = 0;
for (Entry<? extends K, ? extends V> entry : entries) {
// implicit null checks of each array slot
kva[a++] = entry.getKey();
kva[a++] = entry.getValue();
}
return new ImmutableCollections.MapN<>(kva);
}
}
可變參數實現允許我們傳遞可變數量的條目。
例如,我們可以創建一個空地圖:
Map<Long, String> map = Map.ofEntries();
或者我們可以創建並填充地圖:
Map<Long, String> longUserMap = Map.ofEntries(Map.entry(1L, "User A"), Map.entry(2L, "User B"));
Map.ofEntries()
方法的一大優點是我們還可以使用它從現有的鍵和值創建映射。這對於Map.of()
方法是不可能的,因為它只接受未定義的鍵值對作為參數。
4。結論
Map.of()
方法只適用於最多 10 個元素的地圖。這是因為它被實現為 11 個不同的重載方法,這些方法採用 0 到 10 個名稱-值對作為參數。另一方面, Map.ofEntries()
方法可用於任何大小的地圖,因為它利用了特徵變量參數。
GitHub 上提供了完整的示例。