EnumMapのガイド

EnumMapのガイド

1. 概要

EnumMapは、Enumをキーとして排他的に使用するMap の実装です。

このチュートリアルでは、そのプロパティ、一般的な使用例、およびいつ使用する必要があるかについて説明します。

2. プロジェクトのセットアップ

その日にプレイするスポーツと曜日をマッピングする必要があるという単純な要件を想像してください。

Monday     Soccer
Tuesday    Basketball
Wednesday  Hiking
Thursday   Karate

これには、enumを使用できます。

public enum DayOfWeek {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

間もなく表示されるものが、マップの鍵になります。

3. 作成

EnumMapの探索を開始するには、最初に1つをインスタンス化する必要があります。

EnumMap activityMap = new EnumMap<>(DayOfWeek.class);
activityMap.put(DayOfWeek.MONDAY, "Soccer");

そして、これがHashMapのようなもっと一般的なものとの最初の違いです。 HashMapを使用すると、型のパラメーター化で十分です。つまり、new HashMap<>(). However, EnumMap requires the key type in the constructorを使用する必要があります。

3.1. EnumMap Copyコンストラクタ

EnumMapには、2つのコピーコンストラクターも付属しています。 最初は別のEnumMapを取ります:

EnumMap activityMap = new EnumMap<>(DayOfWeek.class);
activityMap.put(DayOfWeek.MONDAY, "Soccer");
activityMap.put(DayOfWeek.TUESDAY, "Basketball");

EnumMap activityMapCopy = new EnumMap<>(dayMap);
assertThat(activityMapCopy.size()).isEqualTo(2);
assertThat(activityMapCopy.get(DayOfWeek.MONDAY)).isEqualTo("Soccer");
assertThat(activityMapCopy.get(DayOfWeek.TUESDAY)).isEqualTo("Basketball");

3.2. Map Copyコンストラクタ

または、if we have a non-empty Map whose key is an enum, then we can do that, too:

Map ordinaryMap = new HashMap();
ordinaryMap.put(DayOfWeek.MONDAY, "Soccer");

EnumMap enumMap = new EnumMap(ordinaryMap);
assertThat(enumMap.size()).isEqualTo(1);
assertThat(enumMap.get(DayOfWeek.MONDAY)).isEqualTo("Soccer");

EnumMap canが既存のエントリからキータイプを判別できるように、マップは空でない必要があることに注意してください。

指定されたマップに複数の列挙型が含まれている場合、コンストラクターはClassCastExceptionをスローします。

4. 要素の追加と取得

EnumMapをインスタンス化した後、put()メソッドを使用してスポーツを追加できます。

activityMap.put(DayOfWeek.MONDAY, "Soccer");

そして、それを取得するには、get()を使用できます。

assertThat(clubMap.get(DayOfWeek.MONDAY)).isEqualTo("Soccer");

5. 要素の確認

特定の日にマッピングが定義されているかどうかを確認するには、containsKey()を使用します。

activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
assertThat(activityMap.containsKey(DayOfWeek.WEDNESDAY)).isTrue();

また、特定のスポーツがキーにマッピングされているかどうかを確認するには、containsValue()を使用します。

assertThat(activityMap.containsValue("Hiking")).isTrue();

5.1. 値としてのnull

現在、nullは、EnumMapの意味的に有効な値です。

nullを「何もしない」と関連付けて、土曜日にマップしましょう。

assertThat(activityMap.containsKey(DayOfWeek.SATURDAY)).isFalse();
assertThat(activityMap.containsValue(null)).isFalse();
activityMap.put(DayOfWeek.SATURDAY, null);
assertThat(activityMap.containsKey(DayOfWeek.SATURDAY)).isTrue();
assertThat(activityMap.containsValue(null)).isTrue();

6. 要素を削除する

特定の日のマップを解除するには、単にremove()

activityMap.put(DayOfWeek.MONDAY, "Soccer");
assertThat(activityMap.remove(DayOfWeek.MONDAY)).isEqualTo("Soccer");
assertThat(activityMap.containsKey(DayOfWeek.MONDAY)).isFalse();

ご覧のとおり、remove(key)はキーに関連付けられた以前の値を返し、null はキーのマッピングがなかった場合に返します。

unmap a particular day only if that day is mapped to a particular activity:を選択することもできます

activityMap.put(DayOfWeek.Monday, "Soccer");
assertThat(activityMap.remove(DayOfWeek.Monday, "Hiking")).isEqualTo(false);
assertThat(activityMap.remove(DayOfWeek.Monday, "Soccer")).isEqualTo(true);

remove(key, value)は、キーが現在指定された値にマップされている場合にのみ、指定されたキーのエントリを削除します。

7. コレクションビュー

通常の地図と同じように、EnumMapを使用すると、3つの異なるビューまたはサブコレクションを持つことができます。

まず、私たちの活動の新しいマップを作成しましょう。

EnumMap activityMap = new EnumMap(DayOfWeek.class);
activityMap.put(DayOfWeek.THURSDAY, "Karate");
activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
activityMap.put(DayOfWeek.MONDAY, "Soccer");

7.1. values

アクティビティマップの最初のビューはvalues() で、名前が示すように、マップ内のすべての値を返します。

Collection values = dayMap.values();
assertThat(values)
  .containsExactly("Soccer", "Hiking", "Karate");

ここで、EnumMap は順序付けられたマップであることに注意してください。 DayOfWeek enumの順序を使用して、エントリの順序を決定します。

7.2. keySet

同様に、keySet()は、キーのコレクションを列挙型の順序で返します。

Set keys = dayMap.keySet();
assertThat(keys)
        .containsExactly(DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY, DayOfWeek.SATURDAY);

7.3. entrySet

最後に、entrySet()はキーと値のペアでマッピングを返します。

assertThat(dayMap.entrySet())
    .containsExactly(
        new SimpleEntry(DayOfWeek.MONDAY, "Soccer"),
        new SimpleEntry(DayOfWeek.WEDNESDAY, "Hiking"),
        new SimpleEntry(DayOfWeek.THURSDAY, "Karate")
    );

マップでの注文は確かに便利です。チュートリアルでは、compares TreeMap to HashMapについて詳しく説明します。

7.4. ミュータビリティ

ここで、元のアクティビティマップに加えた変更は、そのビューのいずれかに反映されることに注意してください。

activityMap.put(DayOfWeek.TUESDAY, "Basketball");
assertThat(values)
    .containsExactly("Soccer", "Basketball", "Hiking", "Karate");

およびその逆;サブビューに対して行った変更は、元のアクティビティマップに反映されます。

values.remove("Hiking");
assertThat(activityMap.containsKey(DayOfWeek.WEDNESDAY)).isFalse();
assertThat(activityMap.size()).isEqualTo(3);

Map interfaceとのEnumMapの契約に従って、サブビューは元のマップに裏打ちされています。

8. EnumMapを使用する場合

8.1. パフォーマンス

Enumをキーとして使用すると、追加のパフォーマンス最適化を行うことができます。like a quicker hash computation since all possible keys are known in advance.

enumをキーとして持つという単純さは、EnumMapは、保存と取得のための非常に単純なロジックを備えたプレーンオールドJavaArrayによってのみバックアップされる必要があることを意味します。 一方、ジェネリックMap の実装では、ジェネリックオブジェクトをキーとして使用することに関連する懸念に対応する必要があります。 たとえば、ハッシュの衝突の可能性に対応するには、HashMap https://www.example.com/java-hashmap [複雑なデータ構造とかなり複雑な保存および取得ロジックが必要です]。

8.2. 機能性

また、私たちが見たように、EnumMap は順序付けられたマップであり、そのビューは列挙型の順序で繰り返されます。 より複雑なシナリオで同様の動作を取得するには、TreeMapまたはLinkedHashMapを確認します。

9. 結論

この記事では、MapインターフェースのEnumMap実装について説明しました。 Enum をキーとして使用する場合、EnumMap canが役立ちます。

このチュートリアルで使用されているすべての例の完全なソースコードは、GitHub projectにあります。