Eine Anleitung zu EnumMap

Eine Anleitung zu EnumMap

1. Überblick

EnumMap ist eineMap -Erleichterung, die ausschließlichEnum als Schlüssel verwendet.

In diesem Tutorial werden die Eigenschaften, allgemeinen Anwendungsfälle und der Zeitpunkt der Verwendung erläutert.

2. Projektaufbau

Stellen Sie sich eine einfache Anforderung vor, bei der wir die Wochentage auf den Sport abbilden müssen, den wir an diesem Tag spielen:

Monday     Soccer
Tuesday    Basketball
Wednesday  Hiking
Thursday   Karate

Dafür könnten wir eine Aufzählung verwenden:

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

Was wir bald sehen werden, wird der Schlüssel für unsere Karte sein.

3. Schaffung

UmEnumMap zu erkunden, müssen wir zunächst eine instanziieren:

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

Und hier ist unser erster Unterschied zu etwas häufigerem wieHashMap. Beachten Sie, dass mitHashMap die Typparametrisierung ausreichend ist, was bedeutet, dass wir mitnew HashMap<>(). However, EnumMap requires the key type in the constructor davonkommen können.

3.1. EnumMap Copy-Konstruktor

EnumMap wird auch mit zwei Kopierkonstruktoren geliefert. Der erste dauert weitereEnumMap:

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-Konstruktor

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

Beachten Sie, dass die Karte nicht leer sein darf, damitEnumMap can den Schlüsseltyp aus einem vorhandenen Eintrag ermittelt.

Wenn die angegebene Map mehr als einen Aufzählungstyp enthält, wirft der KonstruktorClassCastException.

4. Hinzufügen und Abrufen von Elementen

Nachdem wir einEnumMap instanziiert haben, können wir unseren Sport mit derput()-Methode hinzufügen:

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

Und um es abzurufen, können wirget() verwenden:

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

5. Auf Elemente prüfen

Um zu überprüfen, ob für einen bestimmten Tag eine Zuordnung definiert ist, verwenden wircontainsKey():

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

Um zu überprüfen, ob eine bestimmte Sportart einem Schlüssel zugeordnet ist, verwenden wircontainsValue():

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

5.1. null als Wert

Jetzt istnull ein semantisch gültiger Wert fürEnumMap.

Verknüpfen wirnull mit "nichts tun" und ordnen Sie es dem Samstag zu:

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. Elemente entfernen

Um die Zuordnung eines bestimmten Tages aufzuheben, geben wir einfachremove():

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

Wie wir beobachten können, gibtremove(key) den vorherigen Wert zurück, der dem Schlüssel zugeordnet ist, odernull if, wenn für den Schlüssel keine Zuordnung vorhanden war.

Wir können auchunmap a particular day only if that day is mapped to a particular activity: wählen

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

remove(key, value) entfernt den Eintrag für den angegebenen Schlüssel nur, wenn der Schlüssel derzeit dem angegebenen Wert zugeordnet ist.

7. Sammlungsansichten

Genau wie bei normalen Karten können wir mitEnumMap 3 verschiedene Ansichten oder Untersammlungen haben.

Lassen Sie uns zunächst eine neue Karte unserer Aktivitäten erstellen:

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

7.1. values

Die erste Ansicht unserer Aktivitätskarte istvalues() , die, wie der Name schon sagt, alle Werte in der Karte zurückgibt:

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

Beachten Sie hier, dassEnumMap eine geordnete Karte ist. Es verwendet die Reihenfolge desDayOfWeek -Senums, um die Reihenfolge der Einträge zu bestimmen.

7.2. keySet

In ähnlicher Weise gibtkeySet() eine Sammlung der Schlüssel wieder in Aufzählungsreihenfolge zurück:

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

7.3. entrySet

Schließlich gibtentrySet() die Zuordnung in Schlüssel- und Wertpaaren zurück:

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

Das Bestellen in einer Karte kann sicherlich nützlich sein, und wir gehen in unserem Tutorial näher aufcompares TreeMap to HashMap ein.

7.4. Wandlungsfähigkeit

Denken Sie jetzt daran, dass alle Änderungen, die wir an der ursprünglichen Aktivitätskarte vornehmen, in einer ihrer Ansichten berücksichtigt werden:

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

Und umgekehrt; Alle Änderungen, die wir an den Unteransichten vornehmen, werden in der ursprünglichen Aktivitätsübersicht wiedergegeben:

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

ProEnumMap Vertrag mitMap interface werden die Unteransichten durch die ursprüngliche Karte gesichert.

8. Wann wirdEnumMap verwendet?

8.1. Performance

Die Verwendung vonEnum als Schlüssel ermöglicht eine zusätzliche Leistungsoptimierung,like a quicker hash computation since all possible keys are known in advance.

Die Einfachheit,enum als Schlüssel zu haben, bedeutet, dassEnumMap nur durch ein einfaches altes JavaArray mit sehr einfacher Logik zum Speichern und Abrufen gesichert werden muss. Auf der anderen Seite müssen generischeMap -Erleichterungen Bedenken berücksichtigen, die damit zusammenhängen, dass ein generisches Objekt der Schlüssel ist. Zum Beispiel benötigtHashMap https: //www.example.com/java-hashmap [eine komplexe Datenstruktur und eine wesentlich komplexere Speicher- und Abruflogik], um die Möglichkeit einer Hash-Kollision zu berücksichtigen.

8.2. Funktionalität

Wie wir gesehen haben, istEnumMap eine geordnete Karte, da ihre Ansichten in Aufzählungsreihenfolge iterieren. Um ein ähnliches Verhalten für komplexere Szenarien zu erhalten, können wirTreeMap oderLinkedHashMap betrachten.

9. Fazit

In diesem Artikel haben wir die Implementierung derMap-Schnittstelle durchEnumMapuntersucht. Wenn Sie mitEnum als Schlüssel arbeiten, ist derEnumMap -Scan praktisch.

Den vollständigen Quellcode für alle in diesem Lernprogramm verwendeten Beispiele finden Sie inGitHub project.