Java中的不變Map實現

1.概述

有時最好禁止對java.util.Map的修改,例如跨線程共享只讀數據。為此,我們可以使用不可修改的Map或不可變的Map。

在本快速教程中,我們將看到它們之間的區別。然後,我們將介紹創建不可變Map的各種方法。

2.不可修改與不可變

不可修改的Map只是可修改Map的包裝,它不允許直接對其進行修改:

Map<String, String> mutableMap = new HashMap<>();

 mutableMap.put("USA", "North America");



 Map<String, String> unmodifiableMap = Collections.unmodifiableMap(mutableMap);

 assertThrows(UnsupportedOperationException.class,

 () -> unmodifiableMap.put("Canada", "North America"));

但是基礎可變映射仍然可以更改,並且修改也反映在“不可修改”映射中:

mutableMap.remove("USA");

 assertFalse(unmodifiableMap.containsKey("USA"));





 mutableMap.put("Mexico", "North America");

 assertTrue(unmodifiableMap.containsKey("Mexico"));

另一方面,不可變Map包含其自己的私有數據,並且不允許對其進行修改。因此,一旦創建了不可變映射的實例,數據就無法以任何方式更改。

3.Guava的不可變Immutable Map

Guava提供了每個java.util的不可變版本。Map 使用ImmutableMap 。每當我們嘗試對其進行修改時,它將引發UnsupportedOperationException

由於它包含自己的私有數據,因此當原始Map更改時,該數據不會更改。

現在,我們將討論創建ImmutableMap實例的各種方法

3.1。使用copyOf()方法

首先,讓我們使用ImmutableMap.copyOf()方法,該方法返回原始地圖中所有條目的副本:

ImmutableMap<String, String> immutableMap = ImmutableMap.copyOf(mutableMap);

 assertTrue(immutableMap.containsKey("USA"));

不能直接或間接修改:

assertThrows(UnsupportedOperationException.class,

 () -> immutableMap.put("Canada", "North America"));





 mutableMap.remove("USA");

 assertTrue(immutableMap.containsKey("USA"));





 mutableMap.put("Mexico", "North America");

 assertFalse(immutableMap.containsKey("Mexico"));

3.2。使用builder()方法

我們還可以使用ImmutableMap.builder()方法來創建所有條目的副本,如原始地圖所示。

此外,我們可以使用此方法添加原始地圖中不存在的其他條目:

ImmutableMap<String, String> immutableMap = ImmutableMap.<String, String>builder()

 .putAll(mutableMap)

 .put("Costa Rica", "North America")

 .build();

 assertTrue(immutableMap.containsKey("USA"));

 assertTrue(immutableMap.containsKey("Costa Rica"));

與前面的示例相同,我們不能直接或間接修改它:

assertThrows(UnsupportedOperationException.class,

 () -> immutableMap.put("Canada", "North America"));





 mutableMap.remove("USA");

 assertTrue(immutableMap.containsKey("USA"));





 mutableMap.put("Mexico", "North America");

 assertFalse(immutableMap.containsKey("Mexico"));

3.3。使用of()方法

最後,我們可以使用ImmutableMap.of()方法創建具有一組動態提供的條目的不可變地圖。它最多支持五個鍵/值對:

ImmutableMap<String, String> immutableMap

 = ImmutableMap.of("USA", "North America", "Costa Rica", "North America");

 assertTrue(immutableMap.containsKey("USA"));

 assertTrue(immutableMap.containsKey("Costa Rica"));

我們也不能修改它:

assertThrows(UnsupportedOperationException.class,

 () -> immutableMap.put("Canada", "North America"));

4。結論

在這篇快速文章中,我們討論了不可修改映射和不可變映射之間的區別。

我們還研究了創建Guava ImmutableMap的不同方法

而且,與往常一樣,完整的代碼示例可在GitHub上獲得