compareTo & equals

R

RalleII

Gast
Hallo,
ich habe eine Frage zu einem Hinweis den man in der Compareable-API findet (bzw. hier aus dem Java ist auch eine Insel Buch):
"Wichtig ist neben einer Implementierung von compareTo() auch die passende Realisierung in equals(). Sie ist erst dann konsistent, wenn e1.compareTo(e2) == 0 das gleiche Ergebnis wie e1.equals(e2) liefert, wobei e1 und e2 den gleichen Typ besitzen. Ein Verstoß gegen diese Regel kann bei sortierten Mengen schnell Probleme bereiten"


Hm, was kann passieren wenn man das nicht befolgt?

Was ich habe:
Ich habe eine Hilfsstruktur in der ich paar Dinge speicher. Unter anderem ein long-Wert, in dem der Zeitpunkt der letzten Änderung steht.
Nun habe ich bewusst dieser Hilfsstruktur das Compareable-Interface spendiert, dass die Reihenfolge bezüglich des Änderungszeitpunkt zurückgibt.
Das habe ich so gemacht, damit mein TreeSet nach dem Änderungszeitpunkt sortiert ist.

Aber die equals-Methode hat bei mir nichts damit zu tun. Sollten 2 Objekte in der gleichen Millisekunde verändert werden (was aber unwahrscheinlich ist) würde compareTo 0 zurück geben aber da sie nicht gleich sind würde equals false zurückgeben.

Bis jetzt habe ich keine Probleme damit (wahrscheinlich weil es so gut wie nie vorkommt, dass es zwei Objekte mit dem gleichen Änderungszeitpunkt gibt) aber mit welchen Problemen muss ich rechnen?
Wie kann ich das Problem eleganter lösen?

Danke
 

mjustin

Aktives Mitglied
Hm, was kann passieren wenn man das nicht befolgt?
...
Sollten 2 Objekte in der gleichen Millisekunde verändert werden (was aber unwahrscheinlich ist) würde compareTo 0 zurück geben aber da sie nicht gleich sind würde equals false zurückgeben.

Den Fehler kann man dann leicht reproduzieren, indem man Objekte mit gleichen Millisekundenwerten konstruiert und dem TreeSet hinzufügt.

Wenn man dann auf das TreeSet zugreift, in dem e1 und e2 und ein bestimmtes Objekt sucht, wird anhand compareTo gesucht.

Wenn e1 und e2 den gleichen Millisekundenwert enthalten (und damit compareTo implementiert wird), wird das zum Beispiel dazu führen, dass bei treeSet.add(e1); und treeSet.add(e2) das zuerst gespeicherte Objekt e1 durch e2 ersetzt wird.
 

Marco13

Top Contributor
Ja, man muss damit rechnen, dass das eine Element das andere (laut compareTo ja "gleiche") Element überschreibt (AFAIK wird bei der TreeSet nicht nochmal mit equals geprüft). Abhilfe... hm... An welchen Stellen brauchst du die Eigenschaft, dass die Objekte sortiert sind? Im Zweifelsfall muss man wohl mit einer Liste rumhantieren, wo man sortiert löscht und einfügt, aber das in bezug auf die Laufzeit in die Nähe einer TreeSet zu bringen wäre frickelig...
 
N

nillehammer

Gast
Anfangs habe ich auch immer fleißig Comparable implementiert. Mach ich heute garnicht mehr. Man kann für fast alles einen Comparator benutzen. Wenn dieser konsistent zu equals() ist, gut, falls nicht, auch egal.
 
R

RalleII

Gast
Hallo,
danke für eure Antworten.

Dass 2 gleiche Elemente sich überschreiben hab ich gar nicht bedacht. Habe vor kurzen einen eigenen AVL-Baum gebaut, der gleiche Elemente trotzdem aufnehmen kann, weshalb ich diese Problematik wohl nicht bemerkt habe. Aber ok, eigentlich klar, Sets sind ja soweit ich weiß definiert, dass es keine doppelten Einträge geben kann.

Den Satz von oben
"Wichtig ist neben einer Implementierung von compareTo() auch die passende Realisierung in equals(). Sie ist erst dann konsistent, wenn e1.compareTo(e2) == 0 das gleiche Ergebnis wie e1.equals(e2) liefert, wobei e1 und e2 den gleichen Typ besitzen. Ein Verstoß gegen diese Regel kann bei sortierten Mengen schnell Probleme bereiten"

finde ich dann trotzdem irreführend. Da hört es sich so an, als müsste equals auch true zurück geben, wenn compareTo 0 zurück gibt, sonst würde etwas nicht funktionieren.
Wenn ich es nun richtig verstanden habe wollen sie nur darauf hinweisen, dass bei einem compareTo der Tree von einem equals true ausgeht aber man equals trotzdem anders implementieren kann.

Ich habs nun so gelöst, dass ich nicht die Zeit speicher, zu der das Element verändert wurde, sondern einen "Veränderungscounter" habe. Es gibt einen static changeCounter. Dieser wird bei einer Veränderung in einem Element mit lastChange = changeCounter++ zugeteilt.
Ein Überlauf wird auch behandelt.
Somit geh ich dieser Problematik aus dem Weg.


Danke für eure Antworten.
 

Marco13

Top Contributor
Den Satz von oben
"Wichtig ist neben einer Implementierung von compareTo() auch die passende Realisierung in equals(). Sie ist erst dann konsistent, wenn e1.compareTo(e2) == 0 das gleiche Ergebnis wie e1.equals(e2) liefert, wobei e1 und e2 den gleichen Typ besitzen. Ein Verstoß gegen diese Regel kann bei sortierten Mengen schnell Probleme bereiten"

finde ich dann trotzdem irreführend. Da hört es sich so an, als müsste equals auch true zurück geben, wenn compareTo 0 zurück gibt, sonst würde etwas nicht funktionieren.

Das ist auch so!

Wenn ich es nun richtig verstanden habe wollen sie nur darauf hinweisen, dass bei einem compareTo der Tree von einem equals true ausgeht aber man equals trotzdem anders implementieren kann.

"Können" tut man viel, aber es ist trotzdem wichtig, dass das Verhalten der Spezifikation entspricht. Angenommen, in der nächsten Java-Version (oder auch nur in einer anderen Implementierung von SortedSet!) wird (aus welchem Grund auch immer) zusätzlich zu a.compareTo(b)==0 noch überprüft, ob a.equals(b) gilt: Wenn man sich an die Vorgaben gehalten hat, funktioniert alles weiterhin. Wenn nicht: Viel Spaß bei der Fehlersuche...
 

Marco13

Top Contributor
Inferenzmechanismen ;)

Comparable:
The natural ordering for a class C is said to be consistent with equals if and only if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every e1 and e2 of class C.

AND

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.

IMPLIES so in etwa

If a tree set is to correctly implement the Set interface, e1.compareTo(e2)==0 must have the same boolean value as e1.equals(e2) for all its elements
 

ThreadPool

Bekanntes Mitglied
Inferenzmechanismen..., die funktionieren aber nur zuverlässig solange man von gültigen Voraussetzungen ausgeht.

Du beziehst dich mit deinem Zitat - "Das ist auch so!" auf die Aussage - "Da hört es sich so an, als müsste equals auch true zurück geben, wenn compareTo 0 zurück gibt, sonst würde etwas nicht funktionieren." Die sich wiederrum auf eine Aussage über die grundsätzliche Implementierung von compareTo.

Deine Aussage ist dann einfach irrelevant, weil du von einer falschen Voraussetzung ausgegangen bist von der ich nicht sprach nämlich compareTo im Kontext von Java-Set-Implementierungen.

Grundsätzlich darf die compareTo-Methode sehr wohl != 0 sein wenn equals == true ist, was auch eindeutig im Dokumentationstext zu lesen ist inkl. zusätzlicher Bemerkungen wie eine derartige Abweichung zu dokumentieren ist. Und genau damit wollte ich den OT bestätigen der feststellte das der Buchtext irreführend sei.

Deine Anmerkung im Kontext von Java-Set-Implementierungen ist jedoch richtig, wie du auch schlüssig mithilfe der Dokumentation gezeigt hast. Auf diese Problematik der nicht konsistenten Ordnungen wird zusätzlich im Dokumentationstext von Comparable hingewiesen.
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
J compareTo()- und equals-Methode Java Basics - Anfänger-Themen 3
T Datentypen compareTo() u. equals() bei Strings Java Basics - Anfänger-Themen 3
K hashCode, compareTo vs. equals Java Basics - Anfänger-Themen 3
S compareTo() und equals() Java Basics - Anfänger-Themen 6
Cassy3 Generics - CompareTo Java Basics - Anfänger-Themen 21
X compareTo Methode wird ignoriert Java Basics - Anfänger-Themen 7
O compareTo nach mehreren Kriterien Java Basics - Anfänger-Themen 13
J Hashmap langsamer als compareTo? Java Basics - Anfänger-Themen 23
B Methoden compare() und compareTo() Java Basics - Anfänger-Themen 1
P compareTo() Java Basics - Anfänger-Themen 3
C compareTo verwenden Java Basics - Anfänger-Themen 2
J Sortier alternativen mit der compareTo Methode? Java Basics - Anfänger-Themen 6
J TreeSet mit compareTo sortieren Java Basics - Anfänger-Themen 2
K compareTo(String arg) überschreiben Java Basics - Anfänger-Themen 4
N Compiler-Fehler Comparable / compareTo implementierung Java Basics - Anfänger-Themen 2
M CompareTo soll Datum sortieren Java Basics - Anfänger-Themen 2
A Objekte aus 2 Klassen mit compareTo() vergleichen Java Basics - Anfänger-Themen 7
K CompareTo zwei mal benutzen klappt nicht. Java Basics - Anfänger-Themen 2
1 HILFE! Strings mit CompareTo vergleichen Java Basics - Anfänger-Themen 3
T Methoden Wie compareTo() Methode implementieren? Java Basics - Anfänger-Themen 9
T Strings mit compareto vergleichen und array sortieren Java Basics - Anfänger-Themen 14
P Generischer Binärbaum (compareTo Frage) Java Basics - Anfänger-Themen 4
J Probleme mit Comparable, compareTo() Java Basics - Anfänger-Themen 2
R compareTo Liste sortieren Java Basics - Anfänger-Themen 5
L compareTo bei Strings? Java Basics - Anfänger-Themen 4
D OOP mit compareTo Array sortieren (aus zwei Klassen) Java Basics - Anfänger-Themen 3
T compareTo warum geht es nicht? Java Basics - Anfänger-Themen 2
W compareTo für 3 Strings Java Basics - Anfänger-Themen 11
M compareTo-Sortierungsproblem Java Basics - Anfänger-Themen 16
F compareTo - Sortierung nach 2 Argumenten Java Basics - Anfänger-Themen 10
G in compareTo umschreiben Java Basics - Anfänger-Themen 4
A Die "compareTo( )" methode Java Basics - Anfänger-Themen 16
J compareTo Java Basics - Anfänger-Themen 4
G compareTo Java Basics - Anfänger-Themen 12
T Wie geht das mit compareTo Java Basics - Anfänger-Themen 2
M o.compareTo(o) Java Basics - Anfänger-Themen 13
K compareTo in Verbinug mit Arrays.sort() Java Basics - Anfänger-Themen 4
Bierhumpen compareTo. Wie setze ich es ein Java Basics - Anfänger-Themen 11
R compareTo Java Basics - Anfänger-Themen 2
Say Equals Java Basics - Anfänger-Themen 6
W LocalDate vergleichen mit Equals? Java Basics - Anfänger-Themen 7
W Equals-Methode überschreiben bei composition Java Basics - Anfänger-Themen 20
W Wann und warum hashcode und equals? Java Basics - Anfänger-Themen 14
X Datentypen String.equals funktioniert nicht Java Basics - Anfänger-Themen 5
C Long value an Stringbuilder übergeben, equals Methode funktioniert nicht Java Basics - Anfänger-Themen 2
S 2 Strings mit Equals vergleichen Java Basics - Anfänger-Themen 11
lallmichnichtzu Methoden Überladen des .equals-Operators Java Basics - Anfänger-Themen 6
C Objekt1.equals(Objekt2) = immer false. Wieso? Java Basics - Anfänger-Themen 22
NeoLexx equals()-Methode Verständnis Frage anhand Code Beispiel Java Basics - Anfänger-Themen 22
M Objekte mittels equals vergleichen Java Basics - Anfänger-Themen 14
S Interface Equals und hashCode Java Basics - Anfänger-Themen 16
G Java equals() Methode Java Basics - Anfänger-Themen 9
J equals funktioniert nicht - Warum Java Basics - Anfänger-Themen 13
B Date - Vergleich (equals / after) ? Java Basics - Anfänger-Themen 3
G Ratlosigkeit zur Aufgabe im Anhang (boolean, equals.) Java Basics - Anfänger-Themen 20
D Unterschied == und equals in Arrays Java Basics - Anfänger-Themen 2
O equals Methode möglichst effizient Java Basics - Anfänger-Themen 13
H equals methode Java Basics - Anfänger-Themen 1
L Logistiksystem Methode equals und hashcode Java Basics - Anfänger-Themen 20
J Methoden Equals Methode für Integer und Objekte überschreiben? Java Basics - Anfänger-Themen 9
M Erste Schritte Mehrere eingaben in einer Line vergleichen (if equals...) Java Basics - Anfänger-Themen 6
I equals (Override) mit eigener Exception (keine Runtime-Exception) Java Basics - Anfänger-Themen 9
A OOP Richtige Verwendung von ArrayList und equals Java Basics - Anfänger-Themen 24
E equals Prüfung fehlgeschlagen Java Basics - Anfänger-Themen 3
C Objekt equals Java Basics - Anfänger-Themen 2
L String überprüfen mit .equals .contains oder .matches? Java Basics - Anfänger-Themen 1
H equals Methode Java Basics - Anfänger-Themen 1
F String equals NULL Problem Java Basics - Anfänger-Themen 4
D Auf equals von Vaterklasse zugreifen Java Basics - Anfänger-Themen 4
S Methoden equals(object o) / toString Java Basics - Anfänger-Themen 15
E Calender - Equals Problem Java Basics - Anfänger-Themen 14
Psypsy hashCode, equals und toString Java Basics - Anfänger-Themen 3
M Vergleich zweier Array Stellen mit equals/NullpointerException Java Basics - Anfänger-Themen 9
S Unterschiede zwischen equals und contains Java Basics - Anfänger-Themen 2
F Erste Schritte Hilfe bei Übung zu String equals() und Schleifen Java Basics - Anfänger-Themen 8
A Probleme mit equals und get.Text Java Basics - Anfänger-Themen 12
S equals Methode bei String Java Basics - Anfänger-Themen 5
R illegal start of expression - 3 Strings vergleichen mit .equals () Java Basics - Anfänger-Themen 5
K Cast bei equals Java Basics - Anfänger-Themen 2
T SQL equals Java Basics - Anfänger-Themen 4
OnDemand Methoden Equals Methde Java Basics - Anfänger-Themen 3
D if block mit equals im rumpf Java Basics - Anfänger-Themen 11
K Vererbung equals-Methode bei Vererbung abstrakter Klassen Java Basics - Anfänger-Themen 8
SexyPenny90 Wieso ist diese eigene Equals-Methode schlecht? Java Basics - Anfänger-Themen 17
K String - Equals Java Basics - Anfänger-Themen 2
J Klassen Warum ist (a.equals(b)) gleich (a==b)? Java Basics - Anfänger-Themen 13
B Warum gibst hier Equals false zurück ? Java Basics - Anfänger-Themen 23
S Verständnissfrage equals() Java Basics - Anfänger-Themen 2
M Verschiedene Möglichkeiten mit 'equals' abdecken? Java Basics - Anfänger-Themen 9
M Collections Problem bei Überschreibung von hashcode() und equals() bei Hashset-Implementierung Java Basics - Anfänger-Themen 5
W Stringvergleich mit equals Java Basics - Anfänger-Themen 13
C equals() Java Basics - Anfänger-Themen 4
D Problem mit string.equals bzw string.contains Java Basics - Anfänger-Themen 4
T Problem mit der while(!string.equals("x")) Java Basics - Anfänger-Themen 2
E Equals-Methode auf Class-Object Java Basics - Anfänger-Themen 17
X problem mit equals.gelöst Java Basics - Anfänger-Themen 2
J Methode equals() Java Basics - Anfänger-Themen 7
M Equals überschreiben Java Basics - Anfänger-Themen 3
K equals() und hashcode() überschreiben Java Basics - Anfänger-Themen 5
K equals in Hashmap() Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Neue Themen


Oben