Tit   Inh   Ind   1   2   3   4   5   6   7   8   9   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24   25   26   27   28   29   30   31   32   <<   <   >   >> 

12.3 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 Wertes 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 muß. 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, daß 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 

12.3.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.

12.3.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(Objec 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, daß die Suche nach einem Wert sehr 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 sequentiellen Durchlauf durch die Tabelle.

12.3.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, daß 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 weiter oben erklärt, erfolgt der Zugriff daher mit Hilfe der Methoden hasMoreElements und nextElement.

Das folgende Beispiel verdeutlicht die Anwendung einer Hashtable:

001 /* Listing1203.java */
002 
003 import java.util.*;
004 
005 public class Listing1203
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 }
Listing1203.java
Listing 12.3: Anwendung der Klasse Hashtable

 Beispiel 

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:

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

12.3.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 zur Ausgabe (siehe Kapitel 13) und einen Header, der als Kommentar in die Ausgabedatei geschrieben wird. Das Gegenstück zu store ist load, mit der eine Property-Liste gelesen werden kann:

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

Hier muß ein InputStream übergegeben werden (siehe ebenfalls Kapitel 13), der die Daten der Property-Liste zur Verfügung stellt. Wir wollen an dieser Stelle die Betrachtung der Klasse Properties abschließen. Ein ausführliches Beispiel zu ihrer Verwendung findet sich am Ende dieses Kapitels in Abschnitt 12.8.1.

Im JDK 1.1 wurde statt der Methode store die Methode save zum Speichern einer Property-Liste verwendet. Diese hatte dieselbe Signatur, löste aber bei I/O-Problemen keine IOException aus. Im JDK 1.2 wurde save als deprecated deklariert und durch store ersetzt.

 JDK1.1/1.2 


 Tit   Inh   Ind   1   2   3   4   5   6   7   8   9   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24   25   26   27   28   29   30   31   32   <<   <   >   >> 
Go To Java 2, Addison Wesley, Version 1.0.2, © 1999 Guido Krüger, http://www.gkrueger.com