Unveränderliche Kartenimplementierungen in Java

1. Übersicht

Manchmal ist es vorzuziehen, Änderungen an der java.util.Map nicht zuzulassen, z. B. die gemeinsame Nutzung schreibgeschützter Daten zwischen Threads. Zu diesem Zweck können wir entweder eine nicht modifizierbare Karte oder eine unveränderliche Karte verwenden.

In diesem kurzen Tutorial werden wir sehen, was der Unterschied zwischen ihnen ist. Anschließend werden verschiedene Möglichkeiten vorgestellt, wie wir eine unveränderliche Karte erstellen können.

2. Nicht veränderbar oder unveränderlich

Eine nicht modifizierbare Karte ist nur ein Wrapper über eine modifizierbare Karte und erlaubt keine direkten Änderungen daran:

Map mutableMap = new HashMap(); mutableMap.put("USA", "North America"); Map unmodifiableMap = Collections.unmodifiableMap(mutableMap); assertThrows(UnsupportedOperationException.class, () -> unmodifiableMap.put("Canada", "North America"));

Die zugrunde liegende veränderbare Karte kann jedoch weiterhin geändert werden, und die Änderungen werden auch in der nicht veränderbaren Karte wiedergegeben:

mutableMap.remove("USA"); assertFalse(unmodifiableMap.containsKey("USA")); mutableMap.put("Mexico", "North America"); assertTrue(unmodifiableMap.containsKey("Mexico"));

Eine unveränderliche Karte hingegen enthält ihre eigenen privaten Daten und lässt keine Änderungen daran zu. Daher können sich die Daten nach dem Erstellen einer Instanz der unveränderlichen Karte in keiner Weise ändern.

3. Guavas unveränderliche Karte

Guava bietet unveränderliche Versionen jeder java.util . Kartemit ImmutableMap . Es wird eine UnsupportedOperationException ausgelöst, wenn wir versuchen, sie zu ändern.

Da es seine eigenen privaten Daten enthält, ändern sich diese Daten nicht, wenn die ursprüngliche Karte geändert wird.

Wir werden nun verschiedene Möglichkeiten zum Erstellen von Instanzen der ImmutableMap diskutieren .

3.1. Verwendung copyOf () Methode

Verwenden wir zunächst die ImmutableMap.copyOf () -Methode, die eine Kopie aller Einträge wie in der ursprünglichen Zuordnung zurückgibt:

ImmutableMap immutableMap = ImmutableMap.copyOf(mutableMap); assertTrue(immutableMap.containsKey("USA"));

Es kann nicht direkt oder indirekt geändert werden:

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. Verwenden der builder () -Methode

Wir können auch die ImmutableMap.builder () -Methode verwenden, um eine Kopie aller Einträge wie in der Originalkarte zu erstellen.

Darüber hinaus können wir mit dieser Methode zusätzliche Einträge hinzufügen, die in der Originalkarte nicht vorhanden sind:

ImmutableMap immutableMap = ImmutableMap.builder() .putAll(mutableMap) .put("Costa Rica", "North America") .build(); assertTrue(immutableMap.containsKey("USA")); assertTrue(immutableMap.containsKey("Costa Rica"));

Wie im vorherigen Beispiel können wir es nicht direkt oder indirekt ändern:

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. Verwendung der () Methode

Schließlich können wir die ImmutableMap.of () -Methode verwenden, um eine unveränderliche Karte mit einer Reihe von Einträgen zu erstellen, die im laufenden Betrieb bereitgestellt werden. Es werden höchstens fünf Schlüssel / Wert-Paare unterstützt:

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

Wir können es auch nicht ändern:

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

4. Fazit

In diesem kurzen Artikel haben wir die Unterschiede zwischen einer nicht modifizierbaren Karte und einer unveränderlichen Karte erläutert.

Wir haben uns auch verschiedene Möglichkeiten angesehen, Guavas ImmutableMap zu erstellen .

Und wie immer sind die vollständigen Codebeispiele auf GitHub verfügbar.