Java überschreibt equals () und hashcode () für zwei austauschbare Ganzzahlen

8

Ich überschreibe die Methoden equals und hashcode für ein einfaches Containerobjekt für zwei Ints. Jedes int spiegelt den Index eines anderen Objekts wider (es spielt keine Rolle, was dieses Objekt ist). Der Punkt der Klasse besteht darin, eine Verbindung zwischen den beiden Objekten darzustellen.

Die Richtung der Verbindung spielt keine Rolle, daher sollte die equals-Methode unabhängig von der Art und Weise, in der sich die beiden Ints im Objekt befinden (z. B.

), den Wert true zurückgeben %Vor%

Hier ist was ich habe (modifiziert aus dem Quellcode für Integer):

%Vor%

Das funktioniert, aber meine Frage ist: Gibt es einen besseren Weg, dies zu erreichen?

Meine Hauptsorge ist, dass die Methode hashcode () denselben Hashcode für zwei ganze Zahlen zurückgibt, die sich mit der gleichen Zahl multiplizieren. ZB

%Vor%

Die Dokumentation Ссылка , besagt, dass

  

Es ist nicht erforderlich, dass zwei Objekte nicht gleich sind   equals (java.lang.Object) -Methode und ruft dann die Methode hashCode auf   Jedes der beiden Objekte muss eindeutige ganzzahlige Ergebnisse liefern.   Der Programmierer sollte sich jedoch bewusst sein, dass er eindeutig produziert   Ganzzahlige Ergebnisse für ungleiche Objekte können die Leistung von   Hashtabellen.

Wenn jemand eine einfache Möglichkeit sieht, die Anzahl der passenden Hashcodes zu reduzieren, dann wäre ich dankbar für eine Antwort.

Danke!

Tim

PS Ich bin mir bewusst, dass es eine java.sql.Connection gibt, die einige Import-Störungen verursachen könnte. Das Objekt hat tatsächlich einen spezifischeren Namen in meiner Anwendung, aber zur Verkürzung habe ich es hier zu Connection gekürzt.

    
Twice Circled 08.04.2013, 11:30
quelle

5 Antworten

3

Dies ist weithin akzeptierter Ansatz:

%Vor%     
Nikolay Kuznetsov 08.04.2013, 11:32
quelle
6

Drei Lösungen, die "funktionieren", wurden vorgeschlagen. (Mit Arbeit meine ich, dass sie die Grundvoraussetzung eines Hashcodes erfüllen ... dass verschiedene Eingaben unterschiedliche Ausgaben ergeben ... und sie erfüllen auch die zusätzliche "Symmetrie" -Anforderung des OP.)

Dies sind:

%Vor%

Die erste hat das Problem, dass der Bereich des Ausgangs durch den Bereich der tatsächlichen Eingangswerte begrenzt ist. Nehmen wir zum Beispiel an, dass die Eingaben beide nicht negative Zahlen kleiner oder gleich 2 i bzw. 2 j sind, dann wird die Ausgabe kleiner oder gleich 2 sein max (i, j) . Das wird wahrscheinlich zu einer schlechten "Dispersion" <1> in Ihrer Hash-Tabelle ... und zu einer höheren Kollisionsrate führen. (Es gibt auch ein Problem, wenn from == to !)

Der zweite und der dritte sind besser als der erste, aber Sie haben immer noch mehr Kollisionen als wünschenswert, wenn from und to klein sind.

Ich würde eine vierte Alternative vorschlagen, wenn es entscheidend ist, dass Sie Kollisionen für kleine Werte von from und to minimieren.

%Vor%

Dies hat den Vorteil, dass, wenn from und to beide im Bereich 0..2 16 -1 liegen, Sie für jedes einzelne (ungeordnete) Paar einen eindeutigen Hashcode erhalten / p>

1 - Ich weiß nicht, ob das der richtige technische Ausdruck dafür ist ...

    
Stephen C 08.04.2013 12:13
quelle
2

Ich denke, etwas wie

%Vor%

ist gut genug

    
infthi 08.04.2013 11:38
quelle
1

Normalerweise verwende ich XOR für die Hashcode-Methode.

%Vor%     
Jayamohan 08.04.2013 11:40
quelle
0

Ich frage mich, warum niemand die gewöhnlich beste Lösung angeboten hat: Normalisieren Sie Ihre Daten :

%Vor%

Wenn es unmöglich ist, würde ich etwas vorschlagen wie

%Vor%
  • Wenn Sie einen anderen Multiplikator als 31 verwenden, vermeiden Sie Kollisionen wie in dieser Frage .
  • Indem Sie einen großen Multiplikator verwenden, verteilen Sie die Zahlen besser.
  • Indem Sie einen ungeraden Multiplikator verwenden, stellen Sie sicher, dass die Multiplikation bijektiv ist (d. h. keine Information geht verloren).

  • Wenn Sie prim verwenden, erhalten Sie gar nichts , aber jeder tut es und hat keinen Nachteil.

maaartinus 15.06.2014 14:32
quelle