Ich habe eine Klasse, "Accumulator", die die Comparable compareTo-Methode implementiert, und ich versuche, diese Objekte in ein HashSet zu stellen.
Wenn ich () zum HashSet hinzufüge, sehe ich keine Aktivitäten in meiner compareTo-Methode im Debugger, egal wo ich meine Breakpoints gesetzt habe. Außerdem, wenn ich mit den add () s fertig bin, sehe ich mehrere Duplikate innerhalb des Sets.
Was vermassele ich hier? Warum ist es nicht Vergleichen und daher die Duplik zulassen?
Danke, Danke IVR Rächer
Was vermassele ich hier?
HashSet basiert auf hashCode()
, nicht auf compareTo()
. Sie können es mit TreeSet
verwechseln. Stellen Sie in beiden Fällen sicher, dass auch equals()
in einer Weise implementiert wird, die mit der anderen Methode übereinstimmt.
HashSet verwendet die Methoden hashCode()
und equals()
, um zu verhindern, dass Duplikate hinzugefügt werden. Zuerst erhält es den Hash-Code des Objekts, das Sie hinzufügen möchten. Dann findet es den entsprechenden Bucket für diesen Hash-Code und durchläuft jedes Objekt in diesem Bucket mit der equals()
-Methode, um festzustellen, ob bereits identische Objekte im Satz vorhanden sind.
Ihr Debugger bricht nicht bei compareTo()
, weil er niemals mit HashSet
! verwendet wird!
Die Regeln lauten:
Wenn zwei Objekte gleich sind, dann ihre Hash-Codes muss gleich sein.
Aber wenn zwei Objekte 'Hash-Codes sind gleich, dann bedeutet das nicht Die Objekte sind gleich! Es könnte sein dass die beiden Objekte zufällig denselben Hash haben.
Wenn hashCode für zwei Objekte unterschiedliche Werte zurückgibt, wird hereal nicht verwendet. Btw, compareTo hat nichts mit Hashing-Sammlungen zu tun :), sondern sortierte Sammlungen
Ihre Objekte sind Comparable
, und wahrscheinlich haben Sie auch equals()
implementiert, aber HashSets
behandelt Objekthashes und Odds haben Sie hashCode()
nicht implementiert (oder Ihre Implementierung von hashCode()
doesn) gebe den gleichen Hash für zwei Objekte zurück, die (a.equals(b) == true)
sind.
Eine Sache, die die Leute ignorieren, was zu einem großen Fehler führt. Verwenden Sie beim Definieren der equals-Methode immer den Parameter als Objektklasse und konver- tieren Sie das Objekt dann zu Ihrer gewünschten Klasse. Für zB
%Vor%Wenn du passierst Song aSong statt Object aSong zu schreiben, wird deine equals-Methode niemals aufgerufen.
Hoffe, das hilft
Wenn Sie ein Objekt der Klasse Akkumulator erstellen, wird in JVM neuer Platz benötigt und jedes Mal, wenn Sie ein Objekt hinzufügen, ein eindeutiger hashCode zurückgegeben hashSet Es hängt nicht vom Wert des Objekts ab, da Sie die hashCode () -Methode nicht überschrieben haben. Daher wird die Methode Object class hashCode () aufgerufen Das gibt einen eindeutigen Hashcode für jedes Objekt zurück, das in Ihrem Programm erstellt wurde.
Lösung:
Überschreiben Sie die Methoden hashCode () und equals () und wenden Sie Ihre Logik entsprechend den Eigenschaften Ihrer Klasse an. Achten Sie darauf, dass Sie gleich und den Hashcode-Vertrag lesen
Tags und Links java set comparable