Java Collection Framework
Implementierungen: Map
Willemers Informatik-Ecke
Set Java Properties

Die Map stellt einen assoziativen Speicher dar. So wie beim Array über den Index als Schlüssel zugegriffen wird, verwendet eine Map einen beliebigen Schlüssel.

Für die Demonstration der Map eignet sich die Zuordnung des Kfz-Kennzeichens zu den Landkreisen geradezu ideal. Als Schlüssel wird das Kfz-Kennzeichen verwendet, Objekte der Klasse Kreis dienen als Elemente bzw. Werte. Zunächst betrachten wir die Klasse namens Kreis.

public class Kreis {
    private String wo;
    long einwohner;
    Kreis(String w, long e) {
        wo = w; einwohner = e;
    }
    String getWo() {
        return wo;
    }
    long getEinwohner() {
        return einwohner;
    }
}
Als Schlüssel reicht ein einfacher String.

HashMap und sein Vorgänger Hashtable

Mit der Methode put werden Daten eingestellt. Dabei müssen immer der Schlüssel und das Element als Parameter angegeben werden.

Mit der Methode get wird ein Element hervorgeholt. Als Parameter wird der Schlüssel angegeben.

Die Methode containsKey prüft, ob der Schlüssel überhaupt vorhanden ist.

Um eine HashMap zu iterieren, erstellt man eine Set-View über den Schlüssel mit der Methode keySet. Von dieser lässt sich nun ein Iterator bilden, mit dem ein Durchlauf aller Elemente kein Problem darstellt. Die HashMap selbst stellt keinen Iterator zur Verfügung.

Das Beispiel füllt eine Map mit ein paar Kreisen, zeigt das Herausholen des Kreises Pinneberg über dessen Kennzeichen PI, um ihn gleich anschließend zu entfernen. Zuletzt wird die Map über einen Iterator ausgelesen und aufgelistet.

import java.util.HashMap;
import java.util.Set;
import java.util.Iterator;
import java.util.Enumeration;

public class TestHashMap {

    public static void main(String args[]) {
        HashMap<String, Kreis> kfzKennzeichen = new HashMap<String, Kreis>();
        kfzKennzeichen.put("SL", new Kreis("Schleswig-Flensburg",197903));
        kfzKennzeichen.put("HG", new Kreis("Hochtaunusgreis",227425));
        kfzKennzeichen.put("MH", new Kreis("Mühlheim",167344));
        kfzKennzeichen.put("PI", new Kreis("Pinneberg",303481));
        System.out.println("Es gibt " + kfzKennzeichen.size() + " Kennzeichen.");
        if (kfzKennzeichen.containsKey("PI")) {
            System.out.println("PI ist das Kennzeichen von: " + kfzKennzeichen.get("PI").getWo());
        } else {
            System.out.println("Kennzeichen PI unbekannt");
        }
        kfzKennzeichen.remove("PI");
        System.out.println("Eine Liste: ");
        Set<String> s = kfzKennzeichen.keySet();
        Iterator<String> e = s.iterator();
        while (e.hasNext()) {
            String k = (String) e.next();
            System.out.print(k + ": " + kfzKennzeichen.get(k).getWo());
            System.out.print(" (" + kfzKennzeichen.get(k).getEinwohner());
            System.out.println(" Einwohner)");
        }
    }
}

Der Vorgänger: Hashtable

Hashtable ist älter als HashMap und nicht Bestandteil des Java Collections Frameworks, erfüllt aber ähnliche Aufgaben. Aufgrund des Alters findet man ihn in diversen Programmen. Allerdings ist eine Überführung in das Java Collection Framework nicht so einfach möglich, so dass von seiner Verwendung abgeraten wird.

Die Unterschiede liegen darin, dass Hashtable synchronisiert ist, was bei HashMap durch das Programm durchgeführt werden muss. Ein Hashtable erlaubt null-Werte weder als Schlüssel noch als Wert. Ein Auslesen des Hashtable erfolgt nicht über einen Iterator, sondern über eine Enumeration, die ebenfalls nicht zum Java Collection Framework gehört.

import java.util.Hashtable;
import java.util.Enumeration;

public class TestHashtable {

    public static void main(String args[]) {
        Hashtable<String, Kreis> kfzKennzeichen = new Hashtable<String, Kreis>();
        kfzKennzeichen.put("SL", new Kreis("Schleswig-Flensburg",197903));
        kfzKennzeichen.put("HG", new Kreis("Hochtaunusgreis",227425));
        kfzKennzeichen.put("MH", new Kreis("Mühlheim",167344));
        kfzKennzeichen.put("PI", new Kreis("Pinneberg",303481));
        System.out.println("Es gibt " + kfzKennzeichen.size() + " Kennzeichen.");
        if (kfzKennzeichen.containsKey("PI")) {
            System.out.println("PI ist das Kennzeichen von: " + kfzKennzeichen.get("PI").getWo());
        } else {
            System.out.println("Kennzeichen PI unbekannt");
        }
        kfzKennzeichen.remove("PI");
        System.out.println("Eine Liste: ");
        Enumeration e = kfzKennzeichen.keys();
        while (e.hasMoreElements()) {
            String k = (String) e.nextElement();
            System.out.print(k + ": " + kfzKennzeichen.get(k).getWo());
            System.out.print(" (" + kfzKennzeichen.get(k).getEinwohner());
            System.out.println(" Einwohner)");
        }
    }
}

TreeMap und LinkedHashMap

Ein Hash ist zwar sehr schnell, aber unsortiert. Wird eine sortierte Reihenfolge benötigt, kann statt HashMap ein TreeMap verwendet werden. Der LinkedHashMap garantiert die Reihenfolge des Einfügens bei einer höheren Geschwindigkeit als beim TreeMap.
Set Java Properties