Was ist eine Hash-Tabelle?
Eine Hash-Tabelle, auch Hash-Tabelle genannt, ist eine A-Daten Struktur, die eine Zuordnungsbeziehung zwischen Schlüsseln und Werten bereitstellt. Solange ein Schlüssel angegeben ist, kann der passende Wert effizient gefunden werden und die Zeitkomplexität liegt nahe bei O(1).
Empfohlene Online-Lernvideos: Java-Video
Wie Hash-Tabellen funktionieren
Eine Hash-Tabelle ist im Wesentlichen ein Array. Wir wissen, dass auf Arrays basierend auf Indizes wie a[0], a[1], a[2], a[3], a[4] zufällig zugegriffen werden kann. Auf diese Weise ist die Abfrageeffizienz sehr hoch. Wenn wir in einer Hash-Tabelle einen Schlüssel angeben, kann der entsprechende Wert sofort abgefragt werden. Zu diesem Zeitpunkt benötigen wir eine „Übertragungsstation“, um den Schlüssel und den Array-Index auf irgendeine Weise umzuwandeln, und diese Übertragungsstation ist die Hash-Funktion.
Hash-Funktionen werden in verschiedenen Sprachen auf unterschiedliche Weise implementiert. Die in Java verwendete ist HashMap
.
In Java und den meisten objektorientierten Sprachen hat jedes Objekt sein eigenes hashcode
, um verschiedene Objekte zu unterscheiden, und dieser Hashcode ist eine ganzzahlige Variable. Zu diesem Zeitpunkt müssen wir diese ganzzahlige Variable in den Index des Arrays konvertieren. Die einfachste Konvertierungsmethode besteht darin, das Modulo der Array-Länge zu verwenden.
Die Formel lautet wie folgt:
index = HashCode(key) % Array.length
Zum Beispiel:
Gegeben ein Array mit einer Länge von 8, möchten wir den Vaule finden, der dem Schlüssel „001121“ entspricht. und „Der Hashcode von 001121“ ist 1420036703, dann kann der Array-Index durch die folgende Berechnung erhalten werden:
index = HashCode("001121")%Array.length = 1420036703 % 8 = 7
Hash-Tabellen-Lese- und Schreibvorgänge
1. Der Schreibvorgang
Der Schreibvorgang besteht darin, ein neues Schlüssel-Wert-Paar in die Hash-Tabelle einzufügen (im JDK „Eintrag“ genannt).
Die spezifische Methode ist: Konvertieren Sie den Schlüsselwert über eine Hash-Funktion in einen Array-Index und fügen Sie dann den Eintrag an dieser Position im Array ein (beachten Sie, dass es sich um das Schlüssel-Wert-Paar Schlüssel+Wert des Eintrags handelt). nicht nur Wert). Es ist denkbar, dass unterschiedliche Schlüsselwerte in denselben Index umgewandelt werden und es dann zu einem Hash-Konflikt kommt.
Die häufig verwendeten Methoden zur Lösung von Hash-Konflikten sind die Methode der offenen Adressierung und die Methode der verknüpften Liste.
Die Grundidee der offenen Adressierungsmethode ist: Wenn ein Hash-Konflikt auftritt, wird der Eintrag an der nächsten leeren Position im Array platziert, dh einzeln nach hinten verschoben.
Die Grundidee der Methode der verknüpften Liste (angewendet in der HashMap-Sammlungsklasse von Java) besteht darin, dass jedes Element im Array nicht nur ein Eintragsobjekt, sondern auch der Kopfknoten einer verknüpften Liste ist. Jedes Entry-Objekt zeigt über den nächsten Zeiger auf seinen nächsten Entry-Knoten. Wenn ein neues Eintragsobjekt einer widersprüchlichen Array-Position zugeordnet wird, muss es nur in die entsprechende verknüpfte Liste eingefügt werden.
2. Lesevorgänge
Lesevorgänge entsprechen Schreibvorgängen und müssen sich nur mit Konfliktsituationen befassen.
Die konkrete Idee ist: Verwenden Sie die Hash-Funktion, um den zu findenden Schlüsselwert in einen Array-Index umzuwandeln, und prüfen Sie dann, ob der Schlüsselwert an dieser Position im Array der Schlüssel ist, nach dem wir suchen Suchen Sie also den Wert des Eintrags. Andernfalls suchen Sie weiter in der verknüpften Liste, um festzustellen, ob ein entsprechender Schlüsselwert vorhanden ist.
Wenn wir beispielsweise den Wert finden möchten, der dem Schlüssel 002936 entspricht, konvertieren wir zuerst den Schlüssel in einen Array-Index und erhalten den Index 2. Wir überprüfen das Element und stellen fest, dass der Schlüssel des Elements 002947 ist , was wir nicht wollen. Wenn Sie den Schlüssel abfragen, fahren Sie mit der Suche in der verknüpften Liste fort.
3. Erweiterung
Wir wissen, dass eine Array-Erweiterung erforderlich ist, wenn die Anzahl der Elemente im Array die maximale Länge erreicht das Array Wann wird beim Erweitern des Arrays die Hash-Tabelle erweitert?
Wenn die Hash-Tabelle nach dem Einfügen mehrerer Elemente einen bestimmten Sättigungsgrad erreicht, steigt die Wahrscheinlichkeit eines Hash-Konflikts. Zu diesem Zeitpunkt sind viele Elemente an derselben Array-Indexposition überfüllt von Nachbestellung Es hat einen großen Einfluss auf die Leistung von Einfüge- und Abfragevorgängen. Zu diesem Zeitpunkt ist es notwendig, die Hash-Tabelle zu erweitern.
Die Faktoren, die die Erweiterung der Hash-Tabelle beeinflussen, sind:
Capacity,即HashMap的当前长度
LoadFactor,即HashMap的负载因子,默认值为0.75
扩容需要满足的条件:
HashMap.Size >= Capacity X LoadFactor
简单解释为:当哈希表中的条目数超出了当前容量与其加载因子的乘积时,并且要存放的位置已经有元素了(哈希碰撞),这两个条件满足时,需要进项扩容,会将容量扩大为原来的两倍。加载因子默认值0.75,是在空间和时间上的一个折中,加载因子过高(发生冲突可多存放在链表),虽然减少了空间成本,但也增加了查询成本。
扩容的步骤:
扩容不是简单地把散列表的长度扩大,而是经历了下面两个步骤:
1.扩容,创建一个新的Entry空数组,长度时原数组的2倍;
2.重新Hash,遍历原Entry数组,所有的Entry重新Hash到新数组中。
经过扩容,原本拥挤的散列表重新变得稀疏,原有的Entry也重新得到了尽可能均匀的分配。需要注意的是,关于HashMap的实现,JDK8和以前的版本有着很大的不同。当多个Entry被Hash到同一个数组下标位置时,为了提高插入和查找的效率,HashMap会把Entry的链表转化为红黑树这种数据结构。
相关文章教程推荐:java语言入门
Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in Hash-Tabellen in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!