Ich habe die folgende Klasse, die als Teil eines Graphen verwendet wird:
%Vor% Wenn ich Eclipse Source / Generate hashCode() and equals()
verwende, erzeugt es diese Methode:
Das Problem ist, dass diese Methode vom aktuellen Objekt auf ihre Kinder und dann während der Berechnung des hashCodes () des ersten untergeordneten Objekts über das parents.hashCode()
zurück zum ursprünglichen Knoten geht weiß nicht, dass der hashCode () dort bereits berechnet wurde. Es kommt dann wieder in children
des ursprünglichen Knotens und es gibt eine schöne Endlosschleife.
Frage : Wie kann ich überprüfen, dass zwei Instanzen von MyNode
das gleiche Objekt sind und gleichzeitig die Endlosschleife vermeiden? Ist es akzeptabel, einen visited
boolean in der MyNode-Klasse hinzuzufügen, um die Exploration zu stoppen? Oder gibt es eine bessere Lösung?
Danke!
Sie sollten keine Kinder oder Eltern von Knoten verwenden, wenn Sie hashCode
und equals
implementieren. Sie sind veränderbare Eigenschaften. Die Berechnung von hashCode
unterscheidet sich nach dem Ändern der Kanten und führt zu fehlerhaften Maps und Set-Sammlungen.
Implementieren Sie hashCode
und equals
, indem Sie nur unveränderbare Felder verwenden, die einen eindeutigen natürlichen Schlüssel für ein Objekt bilden. Ein Name könnte ein guter Kandidat sein, sofern er nicht geändert werden kann.
Wenn keine unveränderbaren Felder existieren, entweder:
hashCode
und equals
, die Standardeinstellungen sind in Ordnung. Dadurch wird jede Klasseninstanz eindeutig. hashCode
und Vergleich in equals
. Mit dem Operator ==
operator können Sie prüfen, ob zwei Objekte dieselbe Instanz sind:
Wenn Sie ein visited
-Flag verwenden möchten, sollten Sie es mit einem Lookup (zB Map
) implementieren, da Sie nach dem Ausführen des Codes diese Flags zurücksetzen müssen.
Ich schlage vor, parents
/ children
zu ignorieren und stattdessen jedem Knoten eine eindeutige ID hinzuzufügen.
Die einzige Voraussetzung für hashCode()
ist, dass zwei Objekte, die gleich sind, denselben Hash-Wert zurückgeben müssen.
Diese Implementierung würde entsprechen:
%Vor%... weil nichts sagt, dass ungleiche Objekte unterschiedliche Hashcodes haben MÜSSEN.
Natürlich wird hashCode()
besser funktionieren, wenn die Werte verteilt werden können. Sie können alles tun, was Sie wollen, solange Sie die Regel über gleiche Objekte nicht brechen. In normalem Allzweckcode, bei dem ich nicht erwarte, dass die Hashes für die Performance kritisch sind, gebe ich im Allgemeinen nur die Hashcodes eines oder mehrerer signifikanter Felder zurück (z. B. Name in diesem Fall), vorausgesetzt, dass diese Felder bei der Berechnung von beteiligt sind Gleichheit, so dass gleiche Objekte den gleichen Hash haben.
Der Punkt ist, dass Sie wirklich equals
und hashCode
als Paar betrachten müssen, und es ist besser, mit Ihrer Definition von equals zu beginnen.