CodeGym /Java-Blog /Germany /Die Klasse Hashtable Java Hashtable mit Beispielen
Autor
Pavlo Plynko
Java Developer at CodeGym

Die Klasse Hashtable Java Hashtable mit Beispielen

Veröffentlicht in der Gruppe Germany
Die Java-Klasse Hashtable ist eines der ältesten Mitglieder des Java Collection Framework. Sie ist eine Implementierung der mathematischen Datenstruktur der Hash-Tabelle. Ein Java-Hashtable enthält intern Fächer, in denen die Schlüssel/Wertpaare abgelegt werden. Hashtable ist HashMap ziemlich ähnlich. Der bedeutendste Unterschied zwischen ihnen ist, dass Hashtable synchronisiert ist, HashMap jedoch nicht.

Hashtable als Datenstruktur

Hashtable ist eine Datenstruktur, in der Daten als Array gespeichert werden. Jeder Datenwert hat einen eindeutigen Schlüsselwert. Wenn der Schlüssel bekannt ist, kannst du sehr schnell auf die gewünschten Daten zugreifen. Einfüge- und Suchvorgänge sind also schnell und unabhängig von der Datengröße möglich. Eine Hash-Tabelle besteht aus einem Array zur Datenspeicherung und einer Hash-Funktion zur Erzeugung des Index, in dem ein Element gespeichert werden soll. Was ist Hashing? In Java ist das eine Regel, die ein Objekt auf eine Zeichenmenge (den Hash-Code) abbildet. In der Regel wandelt diese Art von Funktion eine große Datenmenge in einen kleinen ganzzahligen Wert um. Hash-Funktionen können variiert werden, aber sie alle haben bestimmte Eigenschaften:
  • Ein bestimmtes Objekt hat einen bestimmten Hash-Code.
  • Zwei gleiche Objekte haben die gleichen Hash-Codes. Das Gegenteil ist nicht der Fall.
  • Wenn zwei Hash-Codes unterschiedlich sind, dann sind die Objekte definitiv nicht identisch.
  • Verschiedene Objekte können den gleichen Hash-Code haben. Dieses sehr seltene Ereignis wird als Kollision bezeichnet. Eine gute Hash-Funktion minimiert die Wahrscheinlichkeit von Kollisionen.
Das Ergebnis der Anwendung der Hash-Funktion auf ein Objekt wird als hashCode bezeichnet.Die Klasse Hashtable Java Hashtable mit Beispielen - 1

Hash-Tabelle (hash table) in Java

Die Klasse Hashtable ist die Implementierung der Datenstruktur einer Hash-Tabelle in Java. Diese Collection wurde früher als das Java Collection Framework erstellt, wurde aber später in dieses aufgenommen. Wie alle „frühen“ Collections (ab Java 1.0) ist eine Hash-Tabelle synchronisiert (fast alle Methoden sind als synchronisiert gekennzeichnet). Aus diesem Grund hat Hashtable erhebliche Leistungsprobleme. Daher wird ab Java 1.2 in den meisten Fällen empfohlen, andere Implementierungen des Map-Interfaces zu verwenden, da diese nicht synchronisiert sind. HashMap ist in der Regel der beste Ersatz. Die Klasse Hashtable<K,V> besteht aus Schlüsseln und Werten. Sie speichert Schlüssel basierend auf dem Hash-Prinzip. Schlüssel-Werte-Paare werden in „Fächern“ gespeichert. Die Fächer bilden zusammen eine „Tabelle“, eine Art internes Array. Hashtable verwendet den Hash-Code des Schlüssels, um das Fach zu bestimmen, dem das Schlüssel/Werte-Paar zugeordnet werden soll. Die Hash-Funktion berechnet aus dem Hash-Code eines Schlüssels eine Fachposition. Diese Funktion gibt eine ganze Zahl für ein Objekt zurück. Wie wir bereits erwähnt haben, haben zwei gleiche Objekte denselben Hash-Code, während zwei ungleiche Objekte nicht immer unterschiedliche Hash-Codes haben müssen. Verschiedene Objekte, die in eine Hash-Tabelle eingefügt werden, können den gleichen Hash-Code haben. Um dieses Problem (Kollision) zu lösen, verwendet eine Hash-Tabelle ein Array von Listen. Alle Paare, die auf dasselbe Fach abgebildet werden, werden in einer Liste gespeichert, und eine Referenz auf die Liste wird im Array-Index gespeichert.

Hashtable-Konstruktoren in Java

  • Hashtable() ist der Standardkonstruktor. Er erzeugt eine leere Hash-Tabelle. (Standard-Anfangskapazität = 11, Füllfaktor =0,75).
  • Hashtable(int size) legt eine Hash-Tabelle der angegebenen Größe an.
  • Hashtable(int size, float fillRatio) erstellt eine Hash-Tabelle mit der angegebenen Größe und dem angegebenen Füllverhältnis.
  • Hashtable(Map m) erstellt eine Hash-Tabelle mit den gleichen Zuordnungen wie die übergebene Map.

Hashtable-Deklaration

Die Java-Klasse Hashtable implementiert die Interfaces Map, Cloneable und Serializable. Sie erweitert die Klasse Dictionary.

Hashtable.java
public class Hashtable<K,V>
    extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable
K ist der Typ der Schlüssel, die von der Abbildung verwaltet werden. V ist der Typ der abgebildeten Werte. Beispiel:

Hashtable<Student, Integer> myHTable = new Hashtable<>();

Hashtable in Java importieren

Java Hashtable befindet sich innerhalb des Pakets java.util. Verwende also import java.util.Hashtable; in deinem Code. Normalerweise gibt dir deine IDE einen Hinweis dazu.

Die wichtigsten Operationen mit Hash-Tabellen

Die wesentlichen Operationen der Hashtable-Klasse sind Abrufen, Einfügen und Entfernen. Hier sind diese drei Operationen:
  • Object get(Objektschlüssel) gibt den Wert des Objekts zurück, das den angegebenen Schlüssel hat. Gibt null zurück, wenn kein solcher Schlüssel gefunden wird.
  • Object put(Objektschlüssel, Objektwert) bildet den angegebenen Schlüssel auf den angegebenen Wert ab. Weder der Schlüssel noch der Wert darf null sein.
  • Object remove(Objektschlüssel) entfernt den Eintrag (Schlüssel und entsprechender Wert) aus der Hash-Tabelle.
Hier sind weitere wichtige Operationen:
  • int size() gibt die Anzahl der Einträge in der Hash-Tabelle zurück.
  • boolean contains(Objektwert) prüft, ob sich der angegebene Wert in der Hash-Tabelle befindet. Wenn ja, gibt die Methode true zurück, andernfalls false.
  • boolean containsValue(Objektwert) prüft, ob sich der angegebene Wert in der Hash-Tabelle befindet. Wenn ja, gibt die Methode true zurück, andernfalls false.
  • void clear() entfernt alle Einträge aus der Hash-Tabelle.
  • boolean containsKey(Objektschlüssel) gibt true zurück, wenn der angegebene Schlüssel in der Hash-Tabelle existiert, andernfalls false.
  • boolean isEmpty() gibt true zurück, wenn die Hash-Tabelle leer ist, oder false, wenn sie mindestens einen Schlüssel enthält.
  • void rehash() vergrößert die Größe der Hash-Tabelle und vergibt neue Hashes für alle ihre Schlüssel.

Implementierung einer Hash-Tabelle, Java-Code:

Erstellen wir einmal eine Klasse Student:

import java.util.Date;
public class Student {
   String surname;
   String name;
   String secondName;
   Long birthday; // Long instead of long is used by Gson/Jackson json parsers and various orm databases

   public Student(String surname, String name, String secondName, Date birthday ){
       this.surname = surname;
       this.name = name;
       this.secondName = secondName;
       this.birthday = birthday == null ? 0 : birthday.getTime();
   }

   @Override
   public int hashCode(){
       //TODO: check for nulls
       return (surname + name + secondName + birthday).hashCode();
   }
   @Override
   public boolean equals(Object other_) {
       Student other = (Student)other_;
       return (surname == null || surname.equals(other.surname) )
               && (name == null || name.equals(other.name))
               && (secondName == null || secondName.equals(other.secondName))
               && (birthday == null || birthday.equals(other.birthday));
   }
}
Hier ist ein Beispiel für Hashtablel in Java. Legen wir zwei Objekte der Klasse Student in die Hash-Tabelle, entfernen dann einige und überprüfen einige Parameter.

public class HashTableExample {
   public static void main(String[] args) {
 
       Hashtable<Student, Integer> myHTable = new Hashtable<>();
       Student sarah1 = new Student("Sarah","Connor", "Jane", null);
       Student john = new Student("John","Connor", "Kyle", new Date(1985, 02-1, 28)); // date not exists
       myHTable.put(john,1);
       myHTable.put(sarah1,0);
       System.out.println(myHTable.get(john));
       System.out.println(myHTable.isEmpty());
       System.out.println(myHTable.size());
       System.out.println(myHTable.contains(1));
       myHTable.remove(john);
       System.out.println(myHTable.contains(0));
       System.out.println(myHTable.contains(1));
       System.out.println(myHTable.containsKey(sarah1));
   }
}
Das Ergebnis der Ausführung des Programms ist:

1
false
2
true
true
false
true

HashMap vs. Hashtable

  • Hashtable ist ähnlich wie HashMap in Java. Der bedeutendste Unterschied besteht darin, dass Hashtable synchronisiert ist, während HashMap nicht synchronisiert ist. Daher ist Hashtable aufgrund der Synchronisierung langsamer als HashMap.
  • Über das Synchronisierungsproblem hinaus lässt Hashtable nicht zu, dass null als Wert oder Schlüssel verwendet wird. HashMap erlaubt einen null-Schlüssel und mehrere null-Werte.
  • Hashtable erbt die Klasse Dictionary, während HashMap die Klasse AbstractMap erbt.
  • HashMap wird von einem Iterator durchlaufen. Hashtable kann nicht nur von einem Iterator, sondern auch von einem Enumerator durchlaufen werden.

Beispiel für Hashtable in Java (Hashtable vs. HashMap null-Schlüssel)

Hier ist ein Codefragment zur Demonstration, wenn null als Schlüssel und Wert in HashMap und Hashtable verwendet wird.

// Null key Java hashtable example and hashmap example  

try{
      System.out.println("Hashtable");
      Hashtable hashTable = new Hashtable();
      hashTable.put(null, new Object());
    }catch(Exception ex){
      ex.printStackTrace();
    }
    System.out.println("HashMap");
    HashMap hashMap = new HashMap();
    hashMap.put(null, new Object());
    System.out.println("as you see no exceptions with null key in HashMap");
  }
Das Ergebnis der Ausführung des Programms, das dieses Fragment enthält, ist:

java.lang.NullPointerException
	at java.base/java.util.Hashtable.put(Hashtable.java:480)
	at Character.main(Character.java:58)
HashMap
as you see no exceptions with null key in HashMap

Fazit

Du wirst Hashtable nicht wirklich oft in echten Projekten verwenden, aber du könntest dieser Datenstruktur in alten Projekten durchaus begegnen. Auf alle Fälle ist es wichtig, zu verstehen, welche Datenstrukturen Java bietet und wie sie funktionieren. Und sei es nur für deine Interviews. Wegen ihrer Ähnlichkeit werden in der Regel HashMap-Objekte anstelle von Hashtable verwendet. HashMap ist performanter (es ist nicht synchronisiert) und kann auch null-Schlüssel haben.
Dieser Beitrag ist auf Englisch verfügbar.
Read the English version of this article to become an expert on the Java Hashtable class. Hash tables are the best kind of hash! :)
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION