08.05 Die Map-Schnittstelle

Bis jetzt haben Sie einfache Datenstrukturen kennengelernt. In diesem Kapitel lernen Sie die Schnittstelle java.util.Map kennen, die sich von den bisher vorgestellten Collections unterscheidet. In einer Map werden die darin gespeicherten Objekte nicht über einen Index (wie bei einer java.util.List) angesprochen, oder in beliebiger Reihenfolge (wie in einem Set) abgespeichert, sondern über einen Schlüssel (Key) identifiziert. Der Schlüssel stellt dabei ein Objekt einer (fast) beliebigen Klasse dar. Folglich kann einem Schlüssel auch nur ein Objekt (Wert, Value) zugeordnet werden. Die Schlüsselklasse sollte zudem die equals und hashCode Methoden korrekt überschreiben.

Allgemeines zu Maps

Zusätzlich zur klassischen Verwendung in Form von Schlüssel-Werte-Paaren einer Map, kann aus einer Map auch ein Set der Schlüssel, und eine Collection der enthaltenen Werte erzeugt werden. Die Reihenfolge, wie die Daten in einer Map liegen und zurückgegeben werden, ist nicht spezifiziert und wird im Zweifelsfall von der jeweiligen Implementierung festgelegt.

Generell sind Maps seit Java 5 generische Klassen. Es wird ein generischer Typ für den Schlüssel (Key), und ein generischer Typ für den Wert (Value) festgelegt.

Genauso wie bei Sets, muss auch bei den Keys einer Map bei der Verwendung von veränderbaren Objekten aufgepasst werden, da nicht festgelegt ist, wie sich eine Map verhält, wenn zwei bereits hinzugefügte Key-Objekte bei einer Veränderung gleich, also equals werden. Ein Beispiel:

public class EqualObject {
  
  private String str;

  public String getStr() {
    return this.str;
  }

  public void setStr(String str) {
    this.str = str;
  }
  
  public int hashCode() {
    return this.str.hashCode();
  }
  
  public boolean equals(Object obj) {
    
    if (obj instanceof EqualObject) {
      if (this.str != null) {
        return this.str.equals(((EqualObject)obj).getStr());
      }
    }
    return false;
  }
}
EqualObject obj1 = new EqualObject();
obj1.setStr("Test");
EqualObject obj2 = new EqualObject();
obj2.setStr("Test2");

Map<EqualObject, String> map = new HashMap<EqualObject, String>();
map.put(obj1, "Ein String");
map.put(obj2, "Ein anderer String");

System.out.println(map.get(obj1)); // Ein String
System.out.println(map.get(obj2)); // Ein anderer String

obj2.setStr(obj1.getStr());

System.out.println(map.get(obj1)); // Ein String
System.out.println(map.get(obj2)); // Ein String

Auch darf eine Map sich nicht selbst als Key beinhalten.

Ebenso wie bei einer Collection, sollte auch eine Map mindestens zwei Konstruktoren bereitstellen. Einen leeren, der eine neue Map erzeugt, und einen, der als Übergabeparameter eine andere Map erhält, deren Inhalte auf diese Map übertragen werden sollen. Auch müssen nicht alle Methoden sinnvoll implementiert werden/sein. Es ist deshalb legitim, dass Methoden, die in der Dokumentation als optional gekennzeichnet sind (z. B. clear, put oder remove), nicht implementiert werden, sondern stattdessen beim Aufruf bspw. eine UnsupportedOperationException werfen.

Beachten Sie, dass nicht jede Map jedes Objekt als Key oder Value akzeptiert. Bspw. unterstützen nicht alle Maps einen null-Key. In solch einem Fall wird meistens eine NullPointerException oder eine ClassCastException geworfen.

Möchten Sie den zugeordneten Wert eines Schlüssels überschreiben, genügt es den Schlüssel mit dem neuen Wert einfach ein weiteres Mal zu setzen.

Methoden einer Map

  • clear() – löscht alle Elemente aus der Map (optional).
  • containsKey(Object key) – gibt true zurück, wenn die Map den entsprechenden Key enthält.
  • containsValue(Object value) – gibt true zurück, wenn die Map den entsprechenden Wert enthält.
  • entrySet() – gibt ein Set der mappings dieser Map zurück.
  • get(Object key) – gibt das Objekt zurück, das mit dem übergebenen Schlüssel assoziiert wird.
  • isEmpty() – gibt true zurück, falls sich keine Einträge in der Map befinden.
  • keySet() – gibt ein Set mit allen Schlüsseln in dieser Map zurück.
  • put(K key, V value) – fügt ein Schlüssel-Werte-Paar der Map hinzu (optional).
  • putAll(Map<? extends K, ? extends V> m) – fügt die Inhalte der übergebenen Map dieser Map hinzu (optional).
  • remove(Object key) – entfernt den übergebenen Schlüssel mitsamt zugeordnetem Wert von der Map (optional).
  • size() – gibt die Anzahl an Schlüssel-Werte-Paaren in der Map zurück.
  • values() – gibt eine Collection zurück, die alle Werte dieser Map enthält.

Verwendung

Eine Map wird immer dann eingesetzt, wenn mehrere Objekte jeweils einem anderen Objekt zugeordnet werden sollen. Dabei kann ein und das selbe Objekt mehreren Objekte-Schlüsseln zugeordnet werden, ein Schlüssel aber nur genau einem Werte-Objekt. Implementierungen der Map lernen Sie im Kapitel 08.08 Implementierungen von Map kennen. An dieser Stelle werfen wir aber noch einen kurzen Blick auf die java.util.HashMap, die in unserem Fall Benutzereigenschaften speichert:

// Map anlegen und befüllen
Map<String, String> properties = new HashMap<String, String>();
properties.put("firstname", "stefan");
properties.put("lastname", "Kiesel");
properties.put("birthday", "14.12.1987");
properties.put("birthplace", "Würzburg");
// Map ausgeben
for (String str : properties.keySet()) {
	System.out.println(str + ": " + properties.get(str));
}
// Werte verändern
properties.put("firstname", "Stefan");
// Gezielt auf einen Wert zugreifen
System.out.println("Hallo " + properties.get("firstname") + "!");

Schreibe einen Kommentar

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.