Java HashSet erlaubt Duplikate; Problem mit vergleichbar?

8

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

    
IVR Avenger 02.06.2010, 20:28
quelle

8 Antworten

15
  

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.

    
Michael Borgwardt 02.06.2010, 20:30
quelle
10

Sie müssen hashCode() und equals() korrekt implementieren.

Sie müssen hashCode überschreiben und eine Zahl basierend auf den Werten in Ihrer Klasse zurückgeben, sodass zwei gleiche Objekte denselben Hashcode haben.

    
SLaks 02.06.2010 20:30
quelle
4

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:

  1. Wenn zwei Objekte gleich sind, dann ihre Hash-Codes muss gleich sein.

  2. 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.

Michael 02.06.2010 20:53
quelle
2

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

    
Mirek Pluta 02.06.2010 20:31
quelle
2

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.

    
Edwin Buck 02.06.2010 20:34
quelle
2

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

    
Atul 04.04.2013 19:49
quelle
1

HashSet verwendet hashCode und equals. TreeSet verwendet die Vergleichsschnittstelle. Hinweis: Wenn Sie sich dafür entscheiden, entweder den Hashcode oder den Gleichheitscode zu überschreiben, sollten Sie den anderen immer überschreiben.

    
sblundy 02.06.2010 20:31
quelle
1

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

Ссылка

    
Rais Alam 14.12.2012 07:45
quelle

Tags und Links