Heim > Technologie-Peripheriegeräte > IT Industrie > So implementieren Sie das HashCode von Java korrekt

So implementieren Sie das HashCode von Java korrekt

尊渡假赌尊渡假赌尊渡假赌
Freigeben: 2025-02-18 10:46:14
Original
621 Leute haben es durchsucht

sitePoint Erforschen Sie die Java -Welt: Laden Sie Java -Entwickler ein,

beizutragen

How to Implement Java's hashCode Correctly

sitePoint erweitert sein Inhaltsfeld weiter und wird sich in naher Zukunft auf Java konzentrieren. Wenn Sie ein erfahrener Java -Entwickler sind und zu unseren Java -Inhalten beitragen möchten, kontaktieren Sie uns bitte, um die Themenideen zu teilen, die Sie schreiben möchten.

korrekte Implementierung von equals und hashCode Methoden in Java

Sie haben die equals -Methode für Ihre Klasse implementiert? Großartig! Sie müssen aber auch die -Methode implementieren. Lassen Sie uns verstehen, warum und wie man es richtig implementiert. hashCode Schlüsselpunkte:

In Java sollten gleiche Objekte denselben Hash -Code haben. Wenn die
    -Methode umgeschrieben wird, muss daher eine passende
  • -Implementierung erstellt werden, um die Genauigkeit und Konsistenz des Speicherns und Abrufen von Objekten in einer Hash-basierten Sammlung sicherzustellen. equals Bei der Implementierung hashCode sollten die gleichen Felder verwendet werden, die in der
  • -Methode verwendet werden. Versuchen Sie, veränderliche Felder und Sammlungen zu vermeiden, da dies zu Leistungsproblemen führen kann.
  • hashCode Hash -Codes hängen mit der Leistungsoptimierung zusammen, sodass Sie nicht zu viel Mühe in das Hashing aufnehmen sollten, es sei denn, die Leistungsanalyse zeigt, dass Verbesserungen erforderlich sind. equals
  • Hash -Kollisionen (zwei verschiedene Objekte haben den gleichen Hash -Code) können durch Verbesserung des Hash -Algorithmus und die Verwendung größerer Primzahlen als Multiplikatoren reduziert werden. Dies hilft, die Hash -Codes im Set gleichmäßiger zu verteilen, die Möglichkeit von Hash -Konflikten zu verringern und ein schnelleres Datenabruf zu gewährleisten.
  • und
Methoden

equals Obwohl die Methode hashCode aus allgemeiner Perspektive angemessen ist, ist die

-Methode technischer. Streng genommen ist es nur ein Implementierungsdetail zur Verbesserung der Leistung.

equals Die meisten Datenstrukturen verwenden die hashCode -Methode, um zu überprüfen, ob sie ein Element enthalten. Zum Beispiel:

equals variable

ist wahr, denn obwohl die Instanzen von "B" nicht gleich sind (wieder ignorieren String -Residency), sind sie gleich.
List<String> list = Arrays.asList("a", "b", "c");
boolean contains = list.contains("b");
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Es ist jedoch ineffizient, jedes Element mit einer an die contains übergebenen Instanz zu vergleichen, während eine Klasse von Datenstrukturen eine effizientere Methode verwendet. Anstatt angeforderte Instanzen mit jedem Element zu vergleichen, das sie enthalten, verwenden sie Verknüpfungen, um die Anzahl der gleichwertigen Instanzen zu verringern und dann nur diese Instanzen zu vergleichen.

Diese Verknüpfung ist der Hash -Code, der als die Gleichheit des Objekts angesehen werden kann, das auf einen Ganzzahlwert reduziert werden soll. Instanzen mit demselben Hash -Code sind nicht unbedingt gleich, aber gleiche Instanzen haben den gleichen Hash -Code. (Oder sollte denselben Hash -Code haben, den wir später diskutieren werden.) Solche Datenstrukturen werden normalerweise nach ihrem technischen Namen benannt, der "Hash" enthält, in dem contains der berühmteste Vertreter ist.

Sie funktionieren normalerweise wie folgt: HashMap

  • Beim Hinzufügen eines Elements wird sein Hash -Code verwendet, um den Index im internen Array (als Eimer bezeichnet) zu berechnen.
  • Wenn andere ungleiche Elemente den gleichen Hash -Code haben, landen sie im selben Eimer und müssen zusammen gebündelt werden, indem sie sie beispielsweise zu einer Liste hinzufügen.
  • Wenn eine Instanz an die contains -Methode übergeben wird, wird der Eimer unter Verwendung seines Hash -Codes berechnet. Nur die Elemente darin werden mit der Instanz verglichen.

Auf diese Weise erfordern die Implementierung der contains -Methode möglicherweise nur sehr wenige, idealerweise ohne equals Vergleiche.

Wie die equals -Methode ist die hashCode -Methode auch in der Object -Klasse definiert.

über Hash nachdenken

Wenn die hashCode -Methode als Verknüpfung verwendet wird, um die Gleichheit zu bestimmen, sollten wir uns wirklich interessieren: Gleiche Objekte sollten denselben Hash -Code haben.

Dies ist auch der Grund, warum wir, wenn wir die equals -Methode neu schreiben, eine passende hashCode -implementierung erstellen müssen! Andernfalls haben Dinge, die gemäß unserer Implementierung gleich sind, möglicherweise nicht den gleichen Hash -Code, da sie die Implementierung der Object -Kläufe verwenden.

hashCode Methodenvereinbarung

Quellcode zitieren:

hashCode Die allgemeine Übereinstimmung der Methode lautet:

  • Wenn es während der Ausführung einer Java -Anwendung mehrmals auf dasselbe Objekt aufgerufen wird, muss die hashCode -Methode immer dieselbe Ganzzahl zurückgeben, sofern die im Vergleich des Objekts verwendeten Informationen nicht geändert werden. Diese Ganzzahl muss zwischen der Ausführung einer Anwendung und der anderen Ausführung derselben Anwendung nicht konsistent sein. equals
  • Wenn zwei Objekte gemäß der
  • -Methode gleich sind, muss der Aufruf zur equals(Object) -Methode auf jedem der beiden Objekte das gleiche ganzzahlige Ergebnis erzeugen. hashCode
  • Wenn die beiden Objekte gemäß der
  • -Methode nicht gleich sind, müssen Sie die equals(Object) -Methode nicht auf den beiden Objekten aufrufen, die unterschiedliche Integer -Ergebnisse erzielen müssen. Programmierer sollten jedoch erkennen, dass die Erzeugung verschiedener Ganzzahlergebnisse für ungleiche Objekte die Leistung der Hash -Tabelle verbessern kann. hashCode
Der erste Punkt spiegelt das Konsistenzattribut der

-Methode wider, und der zweite Punkt sind die Anforderungen, die wir oben gezeichnet haben. Der dritte Punkt zeigt ein wichtiges Detail, das wir später diskutieren werden. equals

implementieren

Methode hashCode

Eine sehr einfache

Implementierung ist wie folgt: Person.hashCode

List<String> list = Arrays.asList("a", "b", "c");
boolean contains = list.contains("b");
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Der menschliche Hash -Code wird berechnet, indem die Hash -Codes verwandter Felder berechnet und zusammen kombiniert werden. Beide bleiben für die Verarbeitung der Versorgungsfunktion

. Objects hash Feld

auswählen

Aber welche Felder sind verwandt? Diese Anforderungen helfen bei der Beantwortung dieser Frage: Wenn ein gleiches Objekt denselben Hash -Code haben muss, sollte die Hash -Code -Berechnung keine Felder enthalten, die nicht für Gleichheitsüberprüfungen verwendet werden. (Ansonsten sind nur zwei Objekte, die auf diesen Feldern unterschiedlich sind, gleich, aber unterschiedliche Hash -Codes.)

Daher sollte der für das Hashing verwendete Satz von Feldern eine Untergruppe der für die Gleichheit verwendeten Felder sein. Standardmäßig werden beide dieselben Felder verwenden, es sind jedoch einige Details zu berücksichtigen.

Konsistenz

Erstens gibt es Konsistenzanforderungen. Es sollte ziemlich streng interpretiert werden. Während es den Hash -Code ermöglicht, sich zu ändern, wenn sich einige Felder ändern (was für veränderliche Klassen häufig unvermeidlich ist), ist die Hash -Datenstruktur für dieses Szenario nicht bereit.

Wie wir oben gesehen haben, wird der Hash -Code verwendet, um den Eimer des Elements zu bestimmen. Wenn sich jedoch die Hash-bezogenen Felder ändern, wird der Hash nicht neu berechnet und das interne Array nicht aktualisiert.

Dies bedeutet, dass nachfolgende Abfragen mit gleichen Objekten oder sogar genau dieselbe Instanz fehlschlagen! Die Datenstruktur berechnet den aktuellen Hash -Code (im Gegensatz zum Hash -Code, der zum Speichern von Instanzen verwendet wird) und sucht danach im falschen Eimer.

Schlussfolgerung: Es ist am besten, keine variablen Felder für die Hash -Code -Berechnung zu verwenden!

Leistung

Die Häufigkeit, mit der der Hash -Code berechnet wird, kann ungefähr die gleiche sein, wenn die

-Methode aufgerufen wird. Dies ist wahrscheinlich im kritischen Leistungsteil des Codes geschehen, daher ist es sinnvoll, die Leistung zu berücksichtigen. Und im Gegensatz zur equals -Methode gibt es hier mehr Raum für die Optimierung. equals

Sofern komplexe Algorithmen verwendet werden oder viele Felder beteiligt sind, sind die arithmetischen Kosten für die Kombination seines Hash -Code so trivial wie die unvermeidlichen Kosten. Überlegen Sie jedoch, ob alle Felder in die Berechnung einbezogen werden müssen! Insbesondere sollte der Satz skeptisch sein. Beispielsweise berechnen Listen und Sammlungen den Hash -Wert für jedes ihrer Elemente. Ob sie aufgerufen werden müssen, sollte auf der Grundlage der Situation berücksichtigt werden.

Wenn die Leistung kritisch ist, ist die Verwendung von

möglicherweise auch nicht die beste Wahl, da ein Array für seine veränderlichen Parameter erstellt werden muss. Objects.hash

Aber die allgemeine Regel zur Optimierung gilt immer noch: Optimieren Sie nicht zu früh! Die Verwendung gemeinsamer Hash -Code -Algorithmen, möglicherweise wird die Aufgabe von Einschlusssätzen und die Optimierung erst nach der Leistungsanalyse erfolgen, zeigt, dass die Möglichkeit einer Verbesserung besteht.

Konflikt

unternehmen alle Ihre Bemühungen, die Leistung zu verfolgen. Wie wäre es mit dieser Implementierung?

List<String> list = Arrays.asList("a", "b", "c");
boolean contains = list.contains("b");
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Es muss schnell sein. Und gleiche Objekte haben den gleichen Hash -Code, daher sind wir in dieser Hinsicht auch in Ordnung. Als Bonus sind keine variablen Felder beteiligt!

Aber erinnerst du dich, was wir vorher über Eimer hatten? Auf diese Weise werden alle Instanzen denselben Eimer eingeben! Dies führt normalerweise zu einer verknüpften Liste, die alle Elemente enthält, was für die Leistung sehr schlecht ist. Beispielsweise löst jeder

-Aufruf einen linearen Scan der verknüpften Liste aus. contains

Daher möchten wir die Anzahl der Elemente im selben Eimer minimieren! Ein Algorithmus, der einen Hash -Code zurückgibt, der selbst für sehr ähnliche Objekte sehr unterschiedlich ist, ist ein guter Anfang. Die Implementierung der Implementierung hängt zum Teil vom ausgewählten Feld ab. Je mehr Details wir in die Berechnung aufnehmen, desto größer ist die Möglichkeit, dass der Hash -Code unterschiedlich ist. Beachten Sie, dass dies genau das Gegenteil von dem ist, was wir über die Leistung denken. Es ist also interessant festzustellen, dass die Verwendung von zu vielen oder zu wenigen Feldern zu einer schlechten Leistung führen kann.

Ein weiterer Teil der Verhinderung von Konflikten ist der Algorithmus, mit dem der Hash tatsächlich berechnet wird.

Hash -Wert

berechnen

Der einfachste Weg, um den Feld -Hash -Code zu berechnen, besteht darin, die

-Methode darauf aufzurufen. Sie können manuell kombiniert werden. Ein gemeinsamer Algorithmus ist es, mit einer willkürlichen Zahl zu beginnen, ihn dann wiederholt mit einer anderen Zahl (normalerweise einer kleinen Primzahl) zu multiplizieren und dann den Hash des Feldes hinzuzufügen: hashCode

List<String> list = Arrays.asList("a", "b", "c");
boolean contains = list.contains("b");
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Dies kann zu Überlauf führen, aber dies verursacht keine Ausnahmen in Java, daher gibt es kein großes Problem.

Beachten Sie, dass selbst hervorragende Hashing -Algorithmen zu ungewöhnlich häufigen Konflikten führen können, wenn die Eingabedaten ein spezifisches Muster aufweisen. Angenommen, wir berechnen den Hash -Wert eines Punktes, indem wir die X- und Y -Koordinaten des Punktes hinzufügen. Das klingt ziemlich gut, bis wir erkennen, dass wir uns oft mit Punkten auf der geraden Linie f (x) = -x befassen, was bedeutet, dass für all diese Punkte x y == 0. Konflikt, viel!

Aber erneut: Verwenden Sie gemeinsame Algorithmen und machen Sie sich keine Sorgen, es sei denn, die Leistungsanalyse zeigt Probleme.

Zusammenfassung

Wir haben gesehen Code.

Dies bedeutet, dass die

-Methode immer neu geschrieben werden muss, wenn die equals -Methode neu geschrieben wird. hashCode

implementieren

Methode: hashCode

    Verwenden Sie dieselben Felder (oder Teilmengen davon) wie in der
  • -Methode. equals
  • Es ist am besten, keine variablen Felder aufzunehmen.
  • Betrachten Sie nicht die
  • -Methode in der Sammlung aufzurufen. hashCode
  • Verwenden Sie gemeinsame Algorithmen, es sei denn, das Muster der Eingabedaten ist das Gegenteil.
Denken Sie daran, dass die

-Methode mit der Leistung zusammenhängt. Verschwenden Sie also nicht zu viel Energie, es sei denn, die Leistungsanalyse zeigt, dass dies erforderlich ist. hashCode

FAQs bei der korrekten Implementierung von Java

Methoden (FAQ) hashCode

Welche Bedeutung hat die

-Methode in Java? hashCode()

Die

-Methode in Java ist eine integrierte Funktion, die einen Ganzzahlwert zurückgibt. Es wird hauptsächlich für Hash-basierte Sammlungen (z. B. hashCode(), HashMap und HashSet) verwendet, um Objekte effizienter zu speichern und abzurufen. Die HashTable -Methode funktioniert in Verbindung mit der hashCode() -Methode, um sicherzustellen, dass jedes Objekt über eine eindeutige Bezeichnung verfügt. Dies hilft, Daten schnell abzurufen, insbesondere in großen Sammlungen, wodurch die Leistung von Java -Anwendungen verbessert wird. equals()

Wie funktioniert die hashCode() -Methode in Java?

Die hashCode() -Methode in Java funktioniert, indem ein ganzzahliger Wert generiert wird, der die Speicheradresse des Objekts darstellt. Dieser Wert wird als Indexnummer des Objekts in einer Hash-basierten Sammlung verwendet. Wenn Sie die hashCode() -Methode auf dem Objekt aufrufen, verwendet sie einen Hashing -Algorithmus, um diese eindeutige Ganzzahl zu generieren. Es ist jedoch wichtig zu beachten, dass zwei verschiedene Objekte möglicherweise den gleichen hashCode haben, was als Hash -Konflikt bezeichnet wird.

Was ist die Konvention zwischen den Methoden

und equals() in hashCode() in Java?

Die Konvention zwischen

und equals() in hashCode() in Java ist eine Reihe von Regeln, die zur Verwaltung ihrer Interaktionen verwendet werden. In der Konvention heißt es, dass der Aufruf zur equals() -Methode auf jedem der beiden Objekte das gleiche Ganzzahl -Ergebnis erzeugen muss, wenn zwei Objekte entsprechend der hashCode() -Methode gleich sind. Dies gewährleistet Konsistenz und Genauigkeit beim Speichern und Abrufen von Objekten in einer Hash-basierten Sammlung.

Wie schreibe ich die hashCode() -Methode in Java neu?

Schreiben Sie die hashCode() in der Java -Methode neu, beinhaltet die Bereitstellung Ihrer eigenen Implementierung, die eine eindeutige Ganzzahl für jedes Objekt zurückgibt. Dies kann durch Verwendung von Instanzvariablen des Objekts und des Primemultiplikators erreicht werden. Primzahlen helfen dabei, die Hash -Codes gleichmäßig im Set zu verteilen, wodurch die Möglichkeit von Hash -Kollisionen verringert wird.

Was ist Hash -Konflikt und wie kann man ihn vermeiden?

Hash -Konflikt bedeutet, dass die hashCode() -Methode die gleiche Ganzzahl für zwei verschiedene Objekte erzeugt. Wenn dies nicht ordnungsgemäß behandelt wird, kann dies zu Datenverlust führen. Um Hash -Konflikte zu vermeiden, können Sie den Hash -Algorithmus verbessern, um einzigartigere ganze Zahlen zu erzeugen. Darüber hinaus kann die Verwendung größerer Primzahlen als Multiplikatoren dazu beitragen, die Hash -Codes im Set gleichmäßiger zu verteilen.

Warum sollte die hashCode() -Methode neu geschrieben werden?

Umschreiben hashCode() Methoden können die Leistung von Java -Anwendungen verbessern, insbesondere im Umgang mit großen Sammlungen. Durch die Bereitstellung Ihrer eigenen Implementierung können Sie einzigartigere und gleichmäßig verteilte Hash -Codes erzeugen, wodurch die Möglichkeit von Hash -Konflikten verringert und ein schnelleres Datenabruf sichergestellt wird.

In Java können zwei ungleiche Objekte dasselbe hashCode haben?

Ja, in Java können zwei ungleiche Objekte dasselbe hashCode haben. Dies wird als Hash -Konflikt bezeichnet. Durch die Verbesserung des Hashing -Algorithmus und die Verwendung einer größeren Primzahl als Multiplikator kann die Möglichkeit reduziert werden.

Was passiert, wenn ich die hashCode() -Methode nicht umschreibe?

Wenn Sie die Methode hashCode() nicht überschreiben, verwendet Java die Standardimplementierung, die für jedes Objekt möglicherweise keinen eindeutigen Hash -Code bereitstellt. Dies kann zu Hash-Konflikten und einem langsameren Datenabruf in Hash-basierten Sammlungen führen.

hashCode() Wie verbessert man die Leistung von Java -Anwendungen?

Die

hashCode() -Methode verbessert die Leistung einer Java -Anwendung, indem für jedes Objekt eine eindeutige Kennung bereitgestellt wird. Auf diese Weise können Daten in Hash-basierten Sammlungen schneller abgerufen werden, da das Objekt direkt mit dem Hash-Code des Objekts gefunden werden kann, ohne die gesamte Sammlung zu durchsuchen.

Kann ich die hashCode() -Methode in einer nicht hashbasierten Sammlung verwenden?

Obwohl die hashCode() -Methode hauptsächlich für Hash-basierte Sammlungen verwendet wird, kann sie auch für nicht hashbasierte Sammlungen verwendet werden. Die Vorteile können jedoch weniger offensichtlich sein, da nicht hashbasierte Sammlungen nicht auf Hash-Code für Datenspeicher und Abruf beruhen.

Das obige ist der detaillierte Inhalt vonSo implementieren Sie das HashCode von Java korrekt. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage