Unveränderliche Kartenimplementierungen in Java

Unveränderliche Kartenimplementierungen in Java

1. Überblick

Manchmal ist es vorzuziehen, Änderungen anjava.util.Map nicht zuzulassen, z. B. schreibgeschützte Daten zwischen Threads zu teilen. 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. Unveränderlich gegen unveränderlich

Eine nicht modifizierbare Karte ist nur ein Wrapper über eine modifizierbare Karte und lässt keine direkten Änderungen zu:

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"));

An Immutable Map, on the other hand, contains its own private data and doesn’t allow modifications to it. 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 liefert unveränderliche Versionen von jeweilsjava.util.Map usingImmutableMap. Es wird einUnsupportedOperationException ausgelöst, wenn wir versuchen, es 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 derImmutableMap. diskutieren

3.1. Verwenden der MethodecopyOf()

Verwenden Sie zunächst dieImmutableMap.copyOf()-Methode, die eine Kopie aller Einträge wie in der Originalkarte zurückgibt:

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

Es kann weder direkt noch 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 Methodebuilder()

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

Darüber hinaus können wir diese Methode verwenden, um zusätzliche Einträge hinzuzufügen, die in der ursprünglichen Map 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 weder direkt noch 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. Verwenden der Methodeof()

Schließlich können wir die MethodeImmutableMap.of()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, GuavasImmutableMap.zu erstellen

Und wie immer sind die vollständigen Codebeispieleover on GitHub verfügbar.