Ich lerne Java Collection Framework und habe ein moderiertes Verständnis. Wenn ich jetzt etwas weiter gehe, habe ich einige Zweifel in Bezug auf: HashMap
, HashSet
, Hashtable
.
Der Javadoc für HashMap
sagt:
Hash-basierte Implementierung der Map-Schnittstelle. Diese Die Implementierung bietet alle optionalen Kartenoperationen und erlaubt Nullwerte und den Nullschlüssel.
Der Javadoc für HashSet
sagt:
Diese Klasse implementiert die Set-Schnittstelle, die durch eine Hashtabelle gesichert wird (eigentlich eine HashMap-Instanz). Es gibt keine Garantie für die Iterationsreihenfolge des Sets; Insbesondere garantiert es nicht, dass Die Reihenfolge bleibt im Laufe der Zeit konstant.
Der Javadoc für Hashtable
sagt:
Diese Klasse implementiert eine Hashtabelle, in der Schlüssel zu Werten zugeordnet werden. Irgendein Nicht-Null-Objekte können als Schlüssel oder als Wert verwendet werden.
Es ist verwirrend, dass alle den hash table
implementieren. Implementieren sie die concept of hash table ?
Es scheint, dass alle diese Dinge miteinander zusammenhängen, aber ich kann es nicht vollständig verstehen.
Kann mir jemand helfen, dieses Konzept in einfacher Sprache zu verstehen.
Javas Set
- und Map
-Schnittstellen geben zwei sehr unterschiedliche Auflistungstypen an. Ein Map
ist konzeptionell genau so, wie es sich anhört: eine Zuordnung von einem Satz von Objekten (den Schlüsseln) zu einem anderen Satz (den Werten). Ein Set
klingt auch so: eine Sammlung von Objekten (ohne andere Struktur). Hashtable
und HashMap
implementieren beide Map
, HashSet
-Implementierungen Set
und verwenden alle Hash-Codes für in den Sammlungen enthaltene Schlüssel/Objekte, um die Leistung zu verbessern.
Hashtable
UND HashMap
Hashtable
ist eine Legacy-Klasse, die fast immer zugunsten von HashMap
vermieden werden sollte. Sie tun im Wesentlichen dasselbe, außer dass die meisten Methoden in Hashtable
synchronisiert sind, wodurch einzelne Methodenaufrufe threadsicher werden.1 Wenn Sie mehrere Threads und HashMap
verwenden, müssen Sie Ihre eigene Synchronisation oder einen anderen Thread-Sicherheitsmechanismus bereitstellen.
Das Problem bei Hashtable
ist, dass das Synchronisieren jedes Methodenaufrufs (was eine nicht unerhebliche Operation ist) normalerweise das Falsche ist. Entweder brauchen Sie überhaupt keine Synchronisation, oder Sie müssen aus Sicht der Anwendungslogik Transaktionen synchronisieren, die sich über mehrere Methodenaufrufe erstrecken. Da es nicht möglich war, die Synchronisierung auf Methodenebene einfach aus Hashtable
zu entfernen, ohne vorhandenen Code zu beschädigen, mussten die Autoren des Collections-Frameworks eine neue Klasse entwickeln. daher HashMap
. Es ist auch ein besserer Name, da klar wird, dass es eine Art von _ Map
ist.
Wenn Sie eine Synchronisation auf Methodenebene benötigen, sollten Sie Hashtable
trotzdem nicht verwenden. Stattdessen können Sie Collections.synchronizedMap()
aufrufen, um aus einer Karte eine synchronisierte zu machen. Alternativ können Sie ConcurrentHashMap
verwenden, das laut the docs : "der gleichen funktionalen Spezifikation wie Hashtable
" gehorcht, jedoch eine bessere Leistung und zusätzliche Funktionalität (z. B. putIfAbsent()
) bietet.
1Es gibt andere Unterschiede (aus meiner Sicht weniger bedeutsam), z. B. HashMap
, die null
-Werte und -Tasten unterstützen.
HashSet
In Bezug auf die Funktionalität hat HashSet
nichts mit HashMap
zu tun. Es kommt vor, dass Sie HashMap
intern verwenden, um die Set
-Funktionalität zu implementieren. Aus irgendeinem Grund dachten die Entwickler des Collections-Frameworks, es wäre eine gute Idee, dieses interne Implementierungsdetail in die öffentliche Spezifikation für die Klasse aufzunehmen. (Dies war aus meiner Sicht ein Fehler.)
Hashtable war eine alte Klasse, die erstellt wurde, bevor Java Generics hatte. Es geht nur noch um Abwärtskompatibilität. Verwenden Sie stattdessen HashMap.
Verwenden Sie HashSet, wenn Sie den Werten keine Schlüssel zuordnen müssen. Es basiert auf demselben Algorithmus wie Hashtabellen, wird jedoch zu einem grundsätzlich anderen Zweck verwendet.
HashMap und HashTable erben beide die Map-Schnittstelle. Sie haben fast identische Funktions- und Eigenschaften. Die Hauptunterschiede sind jedoch wie folgt:
1.Hashmap ist eine ungeordnete Zuordnung von Schlüssel- und Wertepaaren. In einer Hashmap können wir auch die Nullschlüssel- oder Wertepaare enthalten. Außerdem ist eine Hashmap nicht synchronisiert (dh, es können nicht threadsicher mehrere Threads gleichzeitig darauf zugreifen und sie ändern.) Aber wir können extern eine Hashmap threadsafe machen. Wenn wir also die Synchronisationsprobleme nicht berücksichtigen, ist Hashmap vorzuziehen.
2.HashTable: - Eine synchronisierte hashMap (dh eine Thread-sichere Hashmap). Die Schlüssel- und Wertepaare sind in diesem Fall niemals null. In einer Hashtabelle geben wir ein Objekt an, das als Schlüssel verwendet wird, und den gewünschten Wert diesem Schlüssel zuordnen. Der Schlüssel wird dann gehasht und der resultierende Hashcode wird als Index verwendet, an dem der Wert in der Tabelle gespeichert wird
3.HashSet: - Ein Hashset erbt die gesetzte Schnittstelle und letztendlich basiert es auch auf der Hashtable (oder wir können sagen, dass es nur eng mit unserer Hashmap verbunden ist), aber in diesem Fall sind die Schlüssel- und Wertepaare immer eindeutig Schlüsselwerte sind zulässig. Objekte werden basierend auf ihrem Hashcode eingefügt.
Zusammenfassend können wir sagen, dass alle drei Sammlungen mit der Map-Schnittstelle verbunden sind.