Javaにおける不変マップの実装

Javaでの不変マップの実装

1. 概要

スレッド間で読み取り専用データを共有するなど、java.util.Map への変更を許可しない方が望ましい場合があります。 この目的のために、Unmodifiable MapまたはImmutable Mapを使用できます。

このクイックチュートリアルでは、それらの違いを確認します。 次に、不変マップを作成するさまざまな方法を紹介します。

2. 変更不可と不変

変更不可能な地図は、変更可能な地図の単なるラッパーであり、直接変更することはできません。

Map mutableMap = new HashMap<>();
mutableMap.put("USA", "North America");

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

ただし、基礎となる可変マップは引き続き変更でき、変更はUnmodifiableマップにも反映されます。

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.したがって、不変マップのインスタンスが作成されると、データを変更することはできません。

3. グアバの不変マップ

Guavaは、ImmutableMapを使用して各java.utilMap の不変バージョンを提供します。 変更しようとすると、UnsupportedOperationExceptionがスローされます。

独自の個人データが含まれているため、元の地図が変更されてもこのデータは変更されません。

次に、ImmutableMap.のインスタンスを作成するさまざまな方法について説明します。

3.1. copyOf()メソッドの使用

まず、元のマップのようにすべてのエントリのコピーを返すImmutableMap.copyOf()メソッドを使用しましょう。

ImmutableMap 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 immutableMap = ImmutableMap.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()メソッドを使用して、その場で提供される一連のエントリを使用して不変のマップを作成できます。 最大5つのキー/値ペアをサポートします。

ImmutableMap 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. 結論

この簡単な記事では、変更不可能なマップと不変のマップの違いについて説明しました。

また、グアバのImmutableMap.を作成するさまざまな方法も検討しました。

また、いつものように、完全なコード例はover on GitHubで入手できます。