Titel   Inhalt   Suchen   Index   DOC  Handbuch der Java-Programmierung, 7. Auflage
 <<    <     >    >>   API  Kapitel 15 - Collections I

15.4 Die Klasse Hashtable



Die Klasse Hashtable ist eine Konkretisierung der abstrakten Klasse Dictionary. Diese stellt einen assoziativen Speicher dar, der Schlüssel auf Werte abbildet und über den Schlüsselbegriff einen effizienten Zugriff auf den Wert ermöglicht. Ein Dictionary speichert also immer zusammengehörige Paare von Daten, bei denen der Schlüssel als Name des zugehörigen Werts angesehen werden kann. Über den Schlüssel kann später der Wert leicht wiedergefunden werden.

Da ein Dictionary auf unterschiedliche Weise implementiert werden kann, haben die Java-Designer entschieden, dessen abstrakte Eigenschaften in einer Basisklasse zusammenzufassen. Die Implementierung Hashtable benutzt das Verfahren der Schlüsseltransformation, also die Verwendung einer Transformationsfunktion (auch Hash-Funktion genannt), zur Abbildung von Schlüsseln auf Indexpositionen eines Arrays. Weitere Konkretisierungen der Klasse Dictionary, etwa auf der Basis binärer Bäume, gibt es in Java derzeit nicht.

Neben den erwähnten abstrakten Eigenschaften besitzt Hashtable noch die konkreten Merkmale Kapazität und Ladefaktor. Die Kapazität gibt die Anzahl der Elemente an, die insgesamt untergebracht werden können. Der Ladefaktor zeigt dagegen an, bei welchem Füllungsgrad die Hash-Tabelle vergrößert werden muss. Das Vergrößern erfolgt automatisch, wenn die Anzahl der Elemente innerhalb der Tabelle größer ist als das Produkt aus Kapazität und Ladefaktor. Seit dem JDK 1.2 darf der Ladefaktor auch größer als 1 sein. In diesem Fall wird die Hashtable also erst dann vergrößert, wenn der Füllungsgrad größer als 100 % ist und bereits ein Teil der Elemente in den Überlaufbereichen untergebracht wurde.

Wichtig bei der Verwendung der Dictionary-Klassen ist, dass das Einfügen und der Zugriff auf Schlüssel nicht auf der Basis des Operators ==, sondern mit Hilfe der Methode equals erfolgt. Schlüssel müssen daher lediglich inhaltlich gleich sein, um als identisch angesehen zu werden. Eine Referenzgleichheit ist dagegen nicht erforderlich.

 Hinweis 

15.4.1 Einfügen von Elementen

Eine Instanz der Klasse Hashtable kann mit Hilfe eines parameterlosen Konstruktors angelegt werden:

public Hashtable()
java.util.Hashtable

Das Einfügen von Elementen erfolgt durch Aufruf der Methode put:

public Object put(Object key, Object value)
java.util.Hashtable

Dieser Aufruf fügt das Schlüssel-Werte-Paar (key, value) in die Hashtable ein. Weder key noch value dürfen dabei null sein. Falls bereits ein Wertepaar mit dem Schlüssel key enthalten ist, wird der bisherige Wert gegen den neuen ausgetauscht, und put liefert in diesem Fall den Wert zurück, der bisher dem Schlüssel zugeordnet war. Falls der Schlüssel bisher noch nicht vorhanden ist, ist der Rückgabewert null.

15.4.2 Zugriff auf Elemente

Der Zugriff auf ein Element erfolgt mit Hilfe der Methode get über den ihm zugeordneten Schlüssel. get erwartet ein Schlüsselobjekt und liefert den dazu passenden Wert. Falls der angegebene Schlüssel nicht enthalten war, ist der Rückgabewert null:

public Object get(Object key)
java.util.Hashtable

Zusätzlich zu den bisher erwähnten Methoden gibt es noch zwei weitere mit den Namen contains und containsKey. Sie überprüfen, ob ein bestimmter Wert bzw. ein bestimmter Schlüssel in der Hashtable enthalten ist:

public boolean contains(Object value)
public boolean containsKey(Object key)
java.util.Hashtable

Der Rückgabewert ist true, falls das gesuchte Element enthalten ist, andernfalls ist er false. Bei der Verwendung dieser Funktionen ist zu beachten, dass die Suche nach einem Wert wahrscheinlich viel ineffizienter ist als die Suche nach einem Schlüssel. Während der Schlüssel über die Transformationsfunktion sehr schnell gefunden wird, erfordert die Suche nach einem Wert einen sequenziellen Durchlauf durch die Tabelle.

15.4.3 Hashtable als Iterator

In der Klasse Hashtable gibt es zwei Iteratoren, die zur Auflistung von Schlüsseln und Werten verwendet werden können:

public Enumeration elements()
public Enumeration keys()
java.util.Hashtable

Die Methode elements liefert einen Iterator für die Auflistung aller Werte in der Hashtable. In welcher Reihenfolge die Elemente dabei durchlaufen werden, ist nicht definiert. Da eine Hash-Funktion die Eigenschaft hat, Schlüssel gleichmäßig über den verfügbaren Speicher zu verteilen, ist davon auszugehen, dass die Iteratoren ihre Rückgabewerte in einer zufälligen Reihenfolge liefern.

Analog zu elements liefert keys eine Auflistung aller Schlüssel, die sich in der Hash-Tabelle befinden. Wie üblich liefern beide Methoden ein Objekt, welches das Interface Enumeration implementiert. Wie zuvor erklärt, erfolgt der Zugriff daher mit Hilfe der Methoden hasMoreElements und nextElement.

Das folgende Beispiel verdeutlicht die Anwendung einer Hashtable:

001 /* Listing1503.java */
002 
003 import java.util.*;
004 
005 public class Listing1503
006 {
007   public static void main(String[] args)
008   {
009     Hashtable h = new Hashtable();
010 
011     //Pflege der Aliase
012     h.put("Fritz","f.mueller@test.de");
013     h.put("Franz","fk@b-blabla.com");
014     h.put("Paula","user0125@mail.uofm.edu");
015     h.put("Lissa","lb3@gateway.fhdto.northsurf.dk");
016 
017     //Ausgabe
018     Enumeration e = h.keys();
019     while (e.hasMoreElements()) {
020       String alias = (String)e.nextElement();
021       System.out.println(
022         alias + " --> " + h.get(alias)
023       );
024     }
025   }
026 }
Listing1503.java
Listing 15.3: Anwendung der Klasse Hashtable

Das Programm legt eine leere Hashtable an, die zur Aufnahme von Mail-Aliasen verwendet werden soll. Dazu soll zu jeder E-Mail-Adresse ein kurzer Aliasname gepflegt werden, unter dem die lange Adresse später angesprochen werden kann. Das Programm legt zunächst die Aliase »Fritz«, »Franz«, »Paula« und »Lissa« an und assoziiert jeden mit der zugehörigen E-Mail-Adresse. Anschließend durchläuft es alle Schlüssel und gibt zu jedem den dazu passenden Wert aus. Die Ausgabe des Programms ist:

Lissa --> lb3@gateway.fhdto.northsurf.dk
Paula --> user0125@mail.uofm.edu
Franz --> fk@b-blabla.com
Fritz --> f.mueller@test.de

15.4.4 Die Klasse Properties

Die Klasse Properties ist aus Hashtable abgeleitet und repräsentiert ein auf String-Paare spezialisiertes Dictionary, das es erlaubt, seinen Inhalt auf einen externen Datenträger zu speichern oder von dort zu laden. Ein solches Objekt wird auch als Property-Liste (oder Eigenschaften-Liste) bezeichnet. Zur Instanzierung stehen zwei Konstruktoren zur Verfügung:

public Properties()
public Properties(Properties defaults)
java.util.Properties

Der erste legt eine leere Property-Liste an, der zweite füllt sie mit den übergebenen Default-Werten. Der Zugriff auf die einzelnen Elemente erfolgt mit den Methoden getProperty und propertyNames:

public String getProperty(String key)
public String getProperty(String key, String defaultValue)

public Enumeration propertyNames()
java.util.Properties

Die erste Variante von getProperty liefert die Eigenschaft mit der Bezeichnung key. Ist sie nicht vorhanden, wird null zurückgegeben. Die zweite Variante hat dieselbe Aufgabe, gibt aber den Standardwert defaultValue zurück, wenn die gesuchte Eigenschaft nicht gefunden wurde. Mit propertyNames kann ein Enumeration-Objekt beschafft werden, mit dem alle Eigenschaften der Property-Liste aufgezählt werden können.

Zum Speichern einer Property-Liste steht die Methode store zur Verfügung:

public void store(OutputStream out, String header)
  throws IOException
java.util.Properties

Sie erwartet einen OutputStream als Ausgabegerät (siehe Kapitel 20) und einen Header-String, der als Kommentar in die Ausgabedatei geschrieben wird.

Das Gegenstück zu store ist load. Mit ihr kann eine Property-Datei eingelesen werden:

public void load(InputStream in)
  throws IOException
java.util.Properties

Hier muss ein InputStream übergeben werden (siehe ebenfalls Kapitel 20), der die Daten der Property-Liste zur Verfügung stellt.

Property-Dateien sind Textdateien mit einem recht einfachen Aufbau. Je Zeile enthalten sie einen Schlüssel und den zugehörigen Wert. Beide sind durch ein Gleichheitszeichen voneinander getrennt. Falls das erste nichtleere Zeichen einer Zeile ein »#« oder »!« ist, wird die gesamte Zeile als Kommentar angesehen und beim Einlesen ignoriert. Zusätzlich sind einige Escape-Zeichen wie \t, \n, \r, \\, \" oder \' erlaubt und es gibt die Möglichkeit, sehr lange Schlüssel-Wert-Paare auf mehrere Zeilen zu verteilen. Weitere Details können in der API-Dokumentation der Methoden load und store nachgelesen werden.

 Hinweis 

Wir wollen an dieser Stelle die Betrachtung der Klasse Properties abschließen. Ein weiteres Beispiel zu ihrer Verwendung findet sich in Abschnitt 17.3.1.


 Titel   Inhalt   Suchen   Index   DOC  Handbuch der Java-Programmierung, 7. Auflage, Addison Wesley, Version 7.0
 <<    <     >    >>   API  © 1998, 2011 Guido Krüger & Heiko Hansen, http://www.javabuch.de