FB18 - Das Forum für Informatik

fb18.de / Bachelorstudieng / PM Praktische Informatik

Gleichheit und Identität - Blatt 9

Gleichheit und Identität - Blatt 9 2006-02-14 17:18
Viprex
Kann mir einer mal erklären, was nun Gleichheit und Identität bedeutet und was es genau bedeutet, wenn eine Klasse keine eigene equals Methode implementiert? Der Einleitungstext von Blatt 9 ist da etwas komsich in der Formulierung.

Identisch sind Objekte also, wenn es ein und dasselbe Objekt ist, also am selben Speicherplatz steht. Dann ist es auch Gleich.
Objekte können gleich sein, müssen dann aber nicht identisch sein. Gleichheit wird also durch den Zustand (Werte der Exemplarvariablen) bestimmt.
Soweit, so gut denke ich. Jetzt vergleiche ich zwei Integer mit ==. Das geht, weil man direkt Werte damit vergleicht. Vergleiche ich aber zwei Objekte einer Klasse (z. B. 2 Strings) mit ==, dann vergleiche ich deren Referenz. Also ist dies doch ein Vergleich auf Identität, oder?
Jetzt kommen die Probleme:
Daher wird von der Klasse Objekt eine Methode equals(Object obj) implementiert, welche auf Wertgleichheit prüft? Oder was macht die jetzt genau? Aber warum muss ich dann extra eine Methode equals schreiben in einer Klasse, um auf Wertgleichheit zu prüfen?
Sind das spezielle equals Methoden, welche auf ganz andere oder von mir definierte Werte prüfen? Oder prüfen die dann doch wieder auf Identität? Oder kann ich mir das aussuchen (bestimmt, denn ich implmentiere die Methode dann ja selber ;-) ).

Könnte mir hier einer auf die Sprünge helfen? Danke.

Re: Gleichheit und Identität - Blatt 9 2006-02-14 17:23
Marrow
Die equals-Methode von Object vergleicht die Referenzen, ob sie an dieselbe Stelle im Speicher zeigen, also Identität. Will man zwei Objekte als gleich ansehen, wenn 'nur' die Exemplarvariablen die gleichen Werte haben, muss man die Methode überschreiben.

Re: Gleichheit und Identität - Blatt 9 2006-02-14 17:24
joda_der_weise
Ich kann es ja mal probieren: ;)

Prinzipiell gibt es bei Gleichheit von Zahlen keine Probleme, denn z.B. ist 3 = 3 jedem klar.
Wenn Du nun ein Objekt vergleichst, dann ist Gleichheit eigentlich mit Identität gleich zu setzen.
Also wenn Du zum Beispiel fragst, ob dein Objekt1 == Objekt2 ist, ist das nicht richtig, denn richtig wäre Objekt1 == Objekt1.

In der Aufgabe 9 geht es aber darum, zwei Objekte zu vergleichen und eine "eigene Gleichheit" zu definieren.
Hier sollen nämlich zwei Objekte gleich sein, wenn Ihr Zustand, also beispielsweise _wert = 1 ist.
Das ist damit gemeint eine eigene equals-Methode zu bauen.

Also fasse ich einmal kurz zusammen:

3 = 3 -> Gleichheit und Identität
Objekt1 = Objekt1 -> Identität
Objekt2(_wert=1) = Objekt1(_wert=1) -> Gleichheit nach einer Prüfung des Zustands

Alles klar??

Re: Gleichheit und Identität - Blatt 9 2006-02-14 17:25
Hackbert
Die equals-Methode von Object vergleicht die Referenzen, ob sie an dieselbe Stelle im Speicher zeigen…
Eben nicht.

String s1 = "test";
String s2 = "test";

if(s1 == s2) //liefert false
{

}

if(s1.equals(s2)) //liefert true
{

}

Re: Gleichheit und Identität - Blatt 9 2006-02-14 17:36
Marrow
Die equals-Methode von Object vergleicht die Referenzen, ob sie an dieselbe Stelle im Speicher zeigen…
Eben nicht.

String s1 = "test";
String s2 = "test";

if(s1 == s2) //liefert false
{

}

if(s1.equals(s2)) //liefert true
{

}
Das ist die equals-Methode von String, nicht von Object. [img]http://www.fb18.de/gfx/22.gif[/img]

Re: Gleichheit und Identität - Blatt 9 2006-02-14 17:37
UncleOwen
Die equals-Methode von Object vergleicht die Referenzen, ob sie an dieselbe Stelle im Speicher zeigen…
Eben nicht.
Doch. Dein Beispiel testet die equals-Methode von String, nicht die von Object. Wobei Strings eh noch ein Sonderfall sind…

Re: Gleichheit und Identität - Blatt 9 2006-02-14 17:39
Marrow
equals

public boolean equals(Object anObject)

Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.

Overrides:
equals in class Object

Parameters:
anObject - the object to compare this String against.
Returns:
true if the String are equal; false otherwise.
Aus der API von Sun. [img]http://www.fb18.de/gfx/23.gif[/img]
http://java.sun.com/j2se/1.5.0/docs/api/

Re: Gleichheit und Identität - Blatt 9 2006-02-14 17:50
Viprex
Ok, dann habe ich das doch richtig verstanden und der Einleitungstext ist einfach doof formuliert.
Danke!

Re: Gleichheit und Identität - Blatt 9 2006-02-14 17:51
Hackbert
Ok, sorry. Aber in den seltensten Fällen wird man Instanzen von Object miteinander vergleichen wollen.

Re: Gleichheit und Identität - Blatt 9 2006-02-14 18:46
GroßerSchöpfer
Aber vielleicht Dinge die von Object erben …

Re: Gleichheit und Identität - Blatt 9 2006-02-14 19:19
leif
Kann mir einer mal erklären, was nun Gleichheit und Identität bedeutet
Ich kenne den Text des Aufgabenblattes nicht aber so Beschreibungen wie "wir mögen das gleiche Auto haben, aber nicht das selbe" kennst Du?

String s1 = "test";
String s2 = "test";
if(s1 == s2) //liefert false
Stimmt meist nicht, da Java es der Laufzeitumgebung erlaubt einen Pool von Strings zu benutzen. Wenn man "new" aufruft, erhält man aber bei jedem Aufruf ein neues Objekt:String s1 = new String("test"); String s2 = new String("test"); assert s1 != s2; assert s1.equals(s2);Und, ja, "==" und "!=" will man fast nur bei den primitiven Datentypen verwenden. Bei echten Objekten ist in 99.9% der Fälle equals() korrekt.

Re: Gleichheit und Identität - Blatt 9 2006-02-14 20:23
Anonymer User
Objekte werden in Java immer per Referenz angesprochen.

x == y prüft also, ob beide Variablen das selbe Objekt referenzieren. Das nennt man "Identität".

Zwei Objekte sind genau dann gleich, wenn die equals-Methode true zurückliefert. Was in der equals-Methode genau passiert ist dem Programmierer überlassen. Wird diese gar nicht implementiert, dann erbt man die equals-Methode der Klasse Object, welche nichts sinnvolleres machen kann als auf Identität zu prüfen.

Wichtig: wer equals überschreibt, der muss auch hashcode überschreiben!


Fred

Re: Gleichheit und Identität - Blatt 9 2006-02-14 20:59
Viprex
Wichtig: wer equals überschreibt, der muss auch hashcode überschreiben!

Naja, das kann man so pauschal ja auch nicht sagen. Gilt halt nur, wenn du mit Hashcode arbeitest. Der Satz stand auch irgendwo auf den Folien, oder?

Re: Gleichheit und Identität - Blatt 9 2006-02-14 23:22
SNowborn
beim vergleichen mit equals wird auch immer implizit mit verglichen, ob der Hashcode der selbe ist, wenn du bei equals für einen anderen Fall das selbe ergebnis bekommen willst du (und das darin auch so schreibst), aber der Hashcode der objecte noch verschieden ist, gibt die Funktion "false" zurück

Re: Gleichheit und Identität - Blatt 9 2006-02-15 01:53
Brokkoli
beim vergleichen mit equals wird auch immer implizit mit verglichen, ob der Hashcode der selbe ist, wenn du bei equals für einen anderen Fall das selbe ergebnis bekommen willst du (und das darin auch so schreibst), aber der Hashcode der objecte noch verschieden ist, gibt die Funktion "false" zurück

nein… der hashcode ist nur wichtig, wenn man objekte z.b. in hashmaps, hashsets oder ähnlichem speichert, wo der hashcode ausgewertet wird…

z.B. wenn du objekte in einer ArrayList list hast, 2 belibige Objekte o1,o2 mit o1.equals(o2) und o2.equals(o1), von denen o1 in der liste ist - und list.contains(o2) aufrufst, kommt dabei true zurück, unabhängig vom hashCode der objekte. Dieser implizite vergleich, den du da erwähnst existiert nicht.

Re: Gleichheit und Identität - Blatt 9 2006-02-15 10:32
Anonymer User
Wichtig: wer equals überschreibt, der muss auch hashcode überschreiben!
Naja, das kann man so pauschal ja auch nicht sagen. Gilt halt nur, wenn du mit Hashcode arbeitest. Der Satz stand auch irgendwo auf den Folien, oder?
Es ist _sehr_ zu empfehlen hashcode() zu überschreiben, falls man equals() überschreibt. Möglicherweise arbeitet man selber nicht mit dem Hashcode, aber eine der Klassen, an die man eines seiner Objekte übergibt. Oder eine Klasse mit der man arbeitet, verwendete eine Collection, die ….. . Oder man kommt in der Zukunft auf die Idee, diese Objekte in eine Collection zu werfen, welche dann manchmal zur Laufzeit unerwartetes Verhalten zeigt. Oder, oder, oder.

Falls ich equals() überschreibe (was ich aber auch nicht vorschnell mache), dann überschreibe ich immer hashcode(). Und ich empfehle es auch jedem.

LEIFer

Re: Gleichheit und Identität - Blatt 9 2006-02-15 13:26
Viprex
Gilt das denn auch anders herum? Wenn ich hashcode redifiniere, dann auch equals? ;-)

Re: Gleichheit und Identität - Blatt 9 2006-02-15 14:21
Brokkoli
Gilt das denn auch anders herum? Wenn ich hashcode redifiniere, dann auch equals? ;-)

hashCode überscheiben, ohne equals zu überscheiben ist in den meisten fällen völlig sinnlos.. - Wenn 2 objekte den gleichten hashCode haben, aber bei equals false ergeben, sind sie trotzdem nicht gleich..

Eine mögliche Verwendung fällt mir aber doch ein… wenn man einen hashCode hat, der objekte, die man in ein HashSet o.ä. packen will da drinnen optimal verteilt (also zumindest besser als der standard hashCode), könnte man dadurch leichte Geschwindigkeitsvorteile haben…

Re: Gleichheit und Identität - Blatt 9 2006-02-15 14:31
Viprex
Tja, so lautete nämlich eine Frage heute in der Klausur. Ich habs einfach mal nicht angekreuzt. Aus Equals folgt Hashcode redifinieren, aber anders herum wusste ichs halt nicht. Aber das macht dann durchaus Sinn, ja.

Re: Gleichheit und Identität - Blatt 9 2006-02-15 14:38
Anonymer User
Es ist doch ganz einfach: wenn equals true zurückliefert, dann muss der hashcode gleich sein. Wenn man jetzt equals nicht überschreibt, dann wird wird es nur für identische Objekte true zurückliefern, und dann wird auch der hashcode gleich sein, da hashcode ja zweimal auf dem selben Objekt aufgerufen wird.

Man kann also gefahrlos hashcode überschreiben ohne equals zu überschreiben (in dem Sinne, dass die Implikation dann immer noch gilt). Ob das so sinnvoll ist wage ich allerdings zu bezweifeln.

Fred

RE: Gleichheit und Identität - Blatt 9 2009-03-28 17:38
Fred
Pflichtlektüre: Effective Java Chapter 3 - Methods Common to All Objects