sitePoint Erforschen Sie die Java -Welt: Laden Sie Java -Entwickler ein,
beizutragen
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
equals
Bei der Implementierung hashCode
sollten die gleichen Felder verwendet werden, die in der 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
equals
Obwohl die Methode hashCode
aus allgemeiner Perspektive angemessen ist, ist die
equals
Die meisten Datenstrukturen verwenden die hashCode
-Methode, um zu überprüfen, ob sie ein Element enthalten. Zum Beispiel:
equals
variable
List<String> list = Arrays.asList("a", "b", "c"); boolean contains = list.contains("b");
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
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:
Der erste Punkt spiegelt das Konsistenzattribut der
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
Wenn zwei Objekte gemäß derhashCode
-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
- -Methode gleich sind, muss der Aufruf zur
Wenn die beiden Objekte gemäß derequals(Object)
-Methode auf jedem der beiden Objekte das gleiche ganzzahlige Ergebnis erzeugen.hashCode
- -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
-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
Methode hashCode
Implementierung ist wie folgt: Person.hashCode
List<String> list = Arrays.asList("a", "b", "c"); boolean contains = list.contains("b");
. Objects
hash
Feld
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
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
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");
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");
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
Methode: hashCode
equals
hashCode
-Methode mit der Leistung zusammenhängt. Verschwenden Sie also nicht zu viel Energie, es sei denn, die Leistungsanalyse zeigt, dass dies erforderlich ist. hashCode
Methoden (FAQ) hashCode
hashCode()
-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()
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.
equals()
in hashCode()
in Java? 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.
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.
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.
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.
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.
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? 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.
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!