Objekte in TreeSet einfügen + compareTo

MaLb

Mitglied
Hallo zusammen.

Ich versuche Objekte (NavigationNodes) in ein TreeSet zu speichern.
Jedes Objekt hat einen Primärschlüssel (aus einer DB), dessen Eindeutigkeit kann also festgestellt werden.
Die NavigationNodes haben eine CompareTo Methode, die Anhand des Primärschlüssels Werte zurückgibt. Das TreeSet sollte ja jetzt mit Hilfe der CompareTo Methode Duplikate feststellen und diese dann nicht ins TreeSet hinzufügen, was aber leider nicht der Fall ist.

Nachfolgend meine Debugausgaben und entsprechende Kommentare:

Füge das Erste Objekt / NavigationNode in das TreeSet ein (Es existieren aber schon 5 andere Objekte (auch NavigationNodes) im TreeSet

Code:
MSG: Versuche folgenden Knoten in Treeset zu adden (durch User): Knoten [1]: Knowledgebase ;Vorgaenger: 0 ;Ref: ]

Auflistung der bereits existierenden Objekte im TreeSet:
Code:
MSG: Folgende Knoten sind schon in Treeset enthalten: 
MSG:  ... Knoten [7]: KLB Administration ;Vorgaenger: 1 ;Ref: ]
MSG:  ... Knoten [11]: User Administration ;Vorgaenger: 7 ;Ref: Adminformular.jsp]
MSG:  ... Knoten [12]: Beitrags- Administration ;Vorgaenger: 7 ;Ref: Statistikformular.jsp]
MSG:  ... Knoten [61]: AdminNavigation ;Vorgaenger: 7 ;Ref: AdminNavigation.jsp]
MSG:  ... Knoten [92]: Logfile ;Vorgaenger: 7 ;Ref: AdminLogfile.jsp]

Da ja schon 5 Objekte im TreeSet existieren würde ich ja jetzt erwarten, daß
5 mal die Compare Methode aufgerufen wird, aber:

Code:
MSG: [NavigationNode.compareTo] ...
  -->11 :: 1
MSG: [NavigationNode.compareTo] ...
  -->7 :: 1

... sie wird nur 2 mal aufgerufen ... Der neue Knoten wird nur mit Knoten 11 und 7 verglichen. Die Knoten 12, 61 und 92 werden nicht verglichen.

Gleiches Spiel setzt sich fort wenn ich weitere Knoten hinzufüge:

Code:
MSG: Knoten Knoten [1]: Knowledgebase ;Vorgaenger: 0 ;Ref: ] wird in Treeset geschrieben (über User) ...
MSG: Versuche folgenden Knoten in Treeset zu adden (durch User): Knoten [5]: PDM (CDB) ;Vorgaenger: 0 ;Ref: ]
MSG: Folgende Knoten sind schon in Treeset enthalten: 
MSG:  ... Knoten [1]: Knowledgebase ;Vorgaenger: 0 ;Ref: ]
MSG:  ... Knoten [7]: KLB Administration ;Vorgaenger: 1 ;Ref: ]
MSG:  ... Knoten [11]: User Administration ;Vorgaenger: 7 ;Ref: Adminformular.jsp]
MSG:  ... Knoten [12]: Beitrags- Administration ;Vorgaenger: 7 ;Ref: Statistikformular.jsp]
MSG:  ... Knoten [61]: AdminNavigation ;Vorgaenger: 7 ;Ref: AdminNavigation.jsp]
MSG:  ... Knoten [92]: Logfile ;Vorgaenger: 7 ;Ref: AdminLogfile.jsp]
MSG: [NavigationNode.compareTo] ...
  -->11 :: 5
MSG: [NavigationNode.compareTo] ...
  -->7 :: 5
MSG: [NavigationNode.compareTo] ...
  -->1 :: 5

Interessanter Weise (für micht) habe ich das gleiche Bsp schon mit Strings nachprogrammiert (um Konzeptfehler zu finden), da hat dann aber alles sauber funktioniert.
 

zeja

Erfahrenes Mitglied
Hast du equals entsprechend der compareTo implementiert?

Hier ein Ausschnit aus der Doku zu TreeSet:
Note that the ordering maintained by a set (whether or not an explicit comparator is provided) must be consistent with equals if it is to correctly implement the Set interface. (See Comparable or Comparator for a precise definition of consistent with equals.) This is so because the Set interface is defined in terms of the equals operation, but a TreeSet instance performs all element comparisons using its compareTo (or compare) method, so two elements that are deemed equal by this method are, from the standpoint of the set, equal. The behavior of a set is well-defined even if its ordering is inconsistent with equals; it just fails to obey the general contract of the Set interface.
 

MaLb

Mitglied
Habe mittlerweile herausgefunden daß bei einem TreeSet nur die compareTo Methode wichtig ist. Diese Methode wird auch nicht für alle Objekte aufgerufen, sondern nur für welche, die auch wirklich nur anhand der Baumstruktur verglichen werden müssen.
Mit eben entsprechendem Wissen habe ich meinen Fehler - einen Logikfehler in der CompareTo Methode dann auch gefunden.