CodeGym /Kurse /JAVA 25 SELF /Map: HashMap und TreeMap, Schlüssel und Werte

Map: HashMap und TreeMap, Schlüssel und Werte

JAVA 25 SELF
Level 26 , Lektion 2
Verfügbar

1. Einleitung

Im realen Leben treffen wir oft Situationen, in denen jedem eindeutigen „Schlüssel“ ein „Wert“ zugeordnet werden muss. Ein Telefonbuch speichert Telefonnummer und Namen, ein Wörterbuch verknüpft ein Wort mit seiner Übersetzung, und in einer Notentabelle hat jeder Studierende seinen Namen und die entsprechende Punktzahl.

In Java gibt es für solche Aufgaben die Schnittstelle Map. Sie ist eine Sammlung, die Paare „Schlüssel – Wert“ (key-value pair) speichert.

Wesentliche Eigenschaften von Map:

  • Jeder Schlüssel ist eindeutig (Duplikate sind nicht erlaubt).
  • Zu einem Schlüssel kann es nur genau einen Wert geben.
  • Werte dürfen sich wiederholen.

Stellen wir uns eine Analogie vor. Wenn eine Liste (List) wie eine Schlange in der Mensa ist (jede Person hat ihre Position, Zugriff per Index), dann ist eine Map (Map) wie ein Schließfach mit Fächern: Jedes Fach hat eine Nummer (Schlüssel), und darin liegt etwas Eigenes (Wert).

Schnittstelle Map: grundlegende Operationen

Die Schnittstelle Map deklariert die wichtigsten Methoden zum Arbeiten mit Schlüssel-Wert-Paaren:

Methode Beschreibung
put(K key, V value)
Wert für Schlüssel hinzufügen/ersetzen
get(K key)
Wert per Schlüssel abrufen
remove(K key)
Paar per Schlüssel entfernen
containsKey(K key)
Prüfen, ob ein Schlüssel existiert
containsValue(V value)
Prüfen, ob ein Wert existiert
size()
Anzahl der Paare in der Map
isEmpty()
Prüfen, ob die Map leer ist
clear()
Alle Paare entfernen

Die Typen K und V sind Generics: K (Key) – Typ des Schlüssels, V (Value) – Typ des Werts.

3. Klasse HashMap: schneller Zugriff per Schlüssel

Was ist eine HashMap?

HashMap ist die populärste Implementierung der Schnittstelle Map. Sie ermöglicht schnellen Zugriff auf Werte über den Schlüssel.

Wichtig: HashMap garantiert keine Speicherreihenfolge der Elemente! Auch wenn Sie Schlüssel in einer bestimmten Reihenfolge hinzufügen, kann die Iteration eine andere Reihenfolge liefern.

Wie erstellt man eine HashMap?

import java.util.HashMap;
import java.util.Map;

public class Example {
    public static void main(String[] args) {
        // Wir erstellen eine Map: Schlüssel – String, Wert – Integer
        Map<String, Integer> ages = new HashMap<>();

        // Elemente hinzufügen
        ages.put("John", 25);
        ages.put("Peter", 30);
        ages.put("Mary", 22);

        // Wert per Schlüssel abrufen
        int johnAge = ages.get("John");
        System.out.println("Alter von John: " + johnAge); // 25

        // Auf das Vorhandensein eines Schlüssels prüfen
        if (ages.containsKey("Mary")) {
            System.out.println("Mary ist in der Liste!");
        }

        // Element entfernen
        ages.remove("Peter");

        // Alle Schlüssel-Wert-Paare durchlaufen
        for (String name : ages.keySet()) {
            System.out.println(name + ": " + ages.get(name));
        }
    }
}

Ausgabe:

Alter von John: 25
Mary ist in der Liste!
John: 25
Mary: 22

Besonderheiten von HashMap

Das Wichtigste, das man sich merken sollte: Schlüssel in HashMap sind stets eindeutig. Wenn Sie ein neues Element mit einem schon vorhandenen Schlüssel ablegen, wird der alte Wert durch den neuen ersetzt.

Werte dürfen sich wiederholen: Mehrere unterschiedliche Schlüssel können auf denselben Wert zeigen.

Und noch ein wichtiger Punkt – die Reihenfolge der Elemente. HashMap kümmert sich nicht um die Einfügereihenfolge. Beim Ausgeben können die Einträge „durchmischt“ erscheinen – das ist das normale Verhalten.

4. Klasse TreeMap: Sortierung nach Schlüssel

Im Gegensatz zur HashMap speichert die Klasse TreeMap die Elemente in sortierter Reihenfolge nach dem Schlüssel.

Wann sollte man TreeMap verwenden?

Wenn es wichtig ist, dass die Elemente nach aufsteigenden (oder absteigenden) Schlüsseln geordnet sind. Zum Beispiel, wenn Sie ein Telefonbuch alphabetisch ausgeben möchten.

Beispiel:

import java.util.Map;
import java.util.TreeMap;

public class TreeMapExample {
    public static void main(String[] args) {
        Map<String, String> phoneBook = new TreeMap<>();

        phoneBook.put("John", "+1-900-123-45-67");
        phoneBook.put("Mary", "+1-900-555-55-55");
        phoneBook.put("Peter", "+1-900-222-33-44");

        for (String name : phoneBook.keySet()) {
            System.out.println(name + ": " + phoneBook.get(name));
        }
    }
}

Ausgabe:

Mary: +1-900-555-55-55
Peter: +1-900-222-33-44
John: +1-900-123-45-67

Beachten Sie: Die Schlüssel sind alphabetisch sortiert.

5. Grundlegende Operationen mit Map

Hinzufügen und Ersetzen von Einträgen
Map<String, Integer> scores = new HashMap<>();
scores.put("Anna", 90);
scores.put("Robert", 85);
scores.put("Anna", 95); // Überschreibt den Wert für "Anna"
Wert abrufen
Integer annaScore = scores.get("Anna"); // 95
Integer unknown = scores.get("John");   // null, falls es keinen solchen Schlüssel gibt
Prüfen auf Schlüssel oder Wert
scores.containsKey("Robert");    // true
scores.containsValue(85);      // true
Eintrag per Schlüssel entfernen
scores.remove("Robert");
Größe der Map und Leeren
int size = scores.size();
scores.clear(); // Entfernt alle Einträge

5. Elemente einer Map durchlaufen

Map ist keine Liste; es gibt keine Indizes. Man kann aber iterieren:

Über die Schlüssel:

for (String key : scores.keySet()) {
    System.out.println("Schlüssel: " + key + ", Wert: " + scores.get(key));
}

Über die Werte:

for (Integer value : scores.values()) {
    System.out.println("Wert: " + value);
}

Über Schlüssel-Wert-Paare (die beste Methode):

for (Map.Entry<String, Integer> entry : scores.entrySet()) {
    String key = entry.getKey();
    Integer value = entry.getValue();
    System.out.println(key + " => " + value);
}

Wann verwendet man HashMap und wann – TreeMap?

HashMap ist die universelle Variante „per Default“. Wenn die Reihenfolge der Schlüssel egal ist und es vor allem auf Geschwindigkeit ankommt, nimmt man fast immer sie.

TreeMap ist sinnvoll, wenn Ordnung benötigt wird. Sie hält die Schlüssel automatisch sortiert und erlaubt es, den minimalen/maximalen Schlüssel schnell zu finden oder mit Bereichen zu arbeiten.

Fazit: In 90 % der Fälle nehmen wir HashMap. Wenn die Daten sofort „in Ordnung“ sein sollen, verwenden wir TreeMap.

6. Anwendungsbeispiele für Map

Beispiel 1: Telefonbuch

Map<String, String> phoneBook = new HashMap<>();
phoneBook.put("Kate", "+1-999-111-22-33");
phoneBook.put("Oliver", "+1-999-222-33-44");
phoneBook.put("Kate", "+1-999-555-66-77"); // Die alte Nummer von Kate wird durch die neue ersetzt

for (Map.Entry<String, String> entry : phoneBook.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

Ausgabe:

Oliver: +1-999-222-33-44
Kate: +1-999-555-66-77

Beispiel 2: Wortanzahl ermitteln

Angenommen, wir haben eine Liste von Wörtern und möchten wissen, wie oft jedes Wort vorkommt:

import java.util.*;

public class WordCount {
    public static void main(String[] args) {
        List<String> words = Arrays.asList("Apfel", "Banane", "Apfel", "Birne", "Banane", "Apfel");
        Map<String, Integer> counts = new HashMap<>();

        for (String word : words) {
            int oldCount = counts.getOrDefault(word, 0); // wenn es den Schlüssel nicht gibt – 0
            counts.put(word, oldCount + 1);
        }

        System.out.println(counts); // {Birne=1, Apfel=3, Banane=2}
    }
}

7. Typische Fehler im Umgang mit Map

Fehler Nr. 1: Verwechslung von Schlüsseln und Werten. Anfänger versuchen oft, einen Wert per Index wie in einer Liste zu holen oder vergessen, dass Schlüssel eindeutig sein müssen. In der Map gibt es keine Indizes – nur Schlüssel.

Fehler Nr. 2: Verwendung von null-Schlüsseln und -Werten. In der HashMap ist ein null-Schlüssel erlaubt, in der TreeMap jedoch nicht (es gibt eine NullPointerException). Werte dürfen in beiden Implementierungen null sein, sind aber selten sinnvoll.

Fehler Nr. 3: Eine Ordnung in HashMap erwarten. HashMap garantiert keinerlei Ordnung. Wenn Sie Ordnung brauchen – verwenden Sie LinkedHashMap (erhält die Einfügereihenfolge) oder TreeMap (sortiert nach Schlüssel).

Fehler Nr. 4: Map während der Iteration verändern. Wenn Sie eine Map in einer Schleife durchlaufen und gleichzeitig Elemente hinzufügen/entfernen, kann eine ConcurrentModificationException auftreten. Für solche Aufgaben verwenden Sie einen Iterator mit der Methode remove() oder spezielle Collections.

Fehler Nr. 5: Schlüssel und Werte mit == statt equals vergleichen. Map verwendet die Methode equals zum Vergleichen von Schlüsseln (und Werten). Wenn Sie eigene Schlüsselklassen erstellen, überschreiben Sie unbedingt equals und hashCode.

Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION