hashCode bei Objekten

EG2009

Mitglied
Hallo Leute,

Nach stundenlangem Beschäftigen mit dem Thema hashCode bin ich immernoch nicht ganz sicher, ob ich manche Dinge richtig interpretiere.


Wenn ich 2 Objekte einer Klasse erzeuge und die Instanzvariablen in beiden Objekten auf exakt dieselben Werte setze, dann sind die Objekte für mich inhaltlich identisch.

Folgenden Code habe ich eben mal kurz gekritzelt:

Java:
public class ObjekteTest2 {

String titel;
int laenge;

	public static void main(String[] args) {
		ObjekteTest o1 = new ObjekteTest();
		o1.setTitel("hallo");
		o1.setLaenge(23);
		ObjekteTest o2 = new ObjekteTest();
		o2.setTitel("hallo");
		o2.setLaenge(23);
		ObjekteTest o3 = o2;
		
		System.out.println(o1.titel + " " + o1.laenge + " " + o1.hashCode() + " " + o2.titel + " " + 

o2.laenge + " " + o2.hashCode() + " " + o3.titel + " " + o3.laenge + " " + o3.hashCode());

	} // End main

	
		public void setTitel(String s) {
			titel = s;
		}


		public void setLaenge(int zahl) {
			laenge = zahl;
		}
	
} // End class


Frage:
Ist es korrekt, dass ich hier für die beiden Objekte o1 und o2 unterschiedliche Hashcodes erhalte?! Die Objekte sind inhaltlich gleich, aber erzeugen unterschiedliche Hashcodes. Wird der Hashcode dann abhängig vom Speicherort erzeugt, oder wie läuft die Kiste?

Bin grad leider etwas verwirrt ???:L


Wäre super, wenn ihr etwas Licht ins Dunkel bringen könntet.

Besten Dank!

Seb
 

Landei

Top Contributor
Nur du kannst wissen, ob zwei Objekte für dich "inhaltlicht" dieselben sind, deshalb werden standardmäßig allen Objekten verschiedene Hashcodes zugeordnet. Wenn du andere Vorstellungen hast, musst du die equals() und hashCode()-Methoden selbst überschreiben, so dass der Vergleich bzw. der Hashcode genau auf den (für dich) "relevanten" Feldern basiert.

Das Thema ist subtil. Ein paar Beispiele:
-Timestamp erbt von java.util.Date. Sollen ein Timestamp und ein Date, die auf die gleiche Zeit zeigen, "gleich" sein und den gleichen Hashcode bekommen?
- Ist new BigDecimal("2") gleich new BigDecimal("2.000")? (Java sagt nein)
- Sind zwei Excptions mit gleichen Messages und Stacktrace "gleich", auch wenn sie zu unterschiedlichen Zeiten auftreten?
 

Marco13

Top Contributor
"inhaltlich identisch" klingt nach einem etwas widersprüchlichen Oximoron: Sie sind inhaltlich gleich, aber eben nicht identisch. Identisch wären sie, wenn sie beide dasselbe Objekt wären.

Der standard-HashCode wird vermutlich(!) auf Basis von sowas wie einer Speicheradresse berechnet - das spielt keine so große Rolle, es wird leglich versucht (so weit das möglich ist) für unterschiedliche Objekte auch unterschiedliche hashCodes zurückzuliefern.

Wenn man eine eigene Klasse erstellt, und erreichen will, dass zwei "inhaltlich gleiche" Objekte auch den gleichen hashCode haben, muss man die hashCode-Methode überschreiben. In diesem Beispiel könnte das z.B. sowas sein wie
Code:
public int hashCode()
{
    return 31 * titel.hashCode() + laenge;
}
oder so. Fast noch wichtiger ist aber, dass man auch die "equals"-Methode überschreibt - und zwar so, dass sie zur hashCode-Methode passt: Wenn zwei Objekte "equals" sind, müssen auch die hashCodes gleich sein.

Eclipse (und andere IDEs vermulich auch) bietet eine Funktion, um diese Methoden automatisch generieren zu lassen (Source->Generate equals and hashCode)
 

EG2009

Mitglied
Servus Männer,

Danke für eure Rückmeldungen.

Ich weiß nun, wie HashCode und equal zueinander stehen müssen, aber bin immernoch nicht ganz sicher, wie das in der Praxis aussieht. Daher folgende Fragen:

1. Obwohl meine Objekte o1 und o2 inhaltlich äquivalent sind (nennen wir es doch so Marco ;)) geben sie unterschiedliche Hashcodes zurück. 2 Objekte auf dem Heap haben also wirklich niemals denselben Hashcode, wenn die Methode Hashcode von Object nicht überschrieben wird.
Wo wir auch schon beim Punkt meiner Frage sind: Wenn ich Hashcode in meinem Fall oben mit titel.hashCode() überschreibe, dann müsste ich doch für o1 und o2 dasselbe Ergebnis erhalten, oder? Die Titel sind ja gleich?! Irgendwie funzt das aber nicht, da sich der HashCode überhaupt nicht verändert?!

2. Es heißt ja:
"Wenn equals() in einer Klasse nicht überschrieben wird, können 2 verschiedene Objekte niemals als gleich angesehen werden, da Referenzen auf zwei verschiedene Objekte immer ein unterschiedliches Bitmuster enthalten werden."

Ist das Bitmuster auch unterschiedlich, wenn alle Instanzvariablen mit den gleichen Werten belegt sind (wie in meinem Fall oben)? Für mein Verständnis ist das Bitmuster eine Anordnung von 0er und 1er Bits. Bei 2 Objektem mit äquivalentem Inhalt müsste diese Abfolge doch auch identisch sein, oder nicht?!


Besten Dank euch!

Seb
 

Landei

Top Contributor
Es ist eigentlich ganz einfach. Die Standardimplementierung für equals und hashCode ist, dass jedes Objekt nur zu sich selbst "gleich" ist. Der Inhalt der Objekte ist dabei völlig irrelevant:
Java:
class Person {
   public String name; 
   public Person(String name) { this.name = name; }
}

Person a1 = new Person("Alfred");
Person a2 = a1;
Person a3 = new Person("Alfred");
System.out.println(a1.equals(a2)); // true
System.out.println(a1.equals(a3)); // false
Hier zeigt a1 und a2 auf eine andere Speicherstelle als a3, also auf ein anderes Objekt im Speicher. Das kann man auch ganz einfach erkennen, indem man das Attribut name ändert:
Java:
a1.name = "Berthold";
System.out.println(a2.name); // Berthold
System.out.println(a3.name); // Alfred

Will man ein anderes Verhalten (z.B. dass in unserem Beispiel a1 und a3 auch als gleich angesehen werden), muss man es selber implementieren. Dabei sollte man auf die Einhaltung der "Regeln" für equals und hashCode achten, also equals == true --> gleiche Hashcodes.
 

Marco13

Top Contributor
Die Titel sind ja gleich?! Irgendwie funzt das aber nicht, da sich der HashCode überhaupt nicht verändert?!

Meine Glaskugel sagt, dass die IDE meckern würde, wenn du ein [c]@Override[/i] vor die hashCode-Methode schreiben würdest ;) Mal im Ernst: Poste sie vielleicht mal.


Ist das Bitmuster auch unterschiedlich, wenn alle Instanzvariablen mit den gleichen Werten belegt sind (wie in meinem Fall oben)? Für mein Verständnis ist das Bitmuster eine Anordnung von 0er und 1er Bits. Bei 2 Objektem mit äquivalentem Inhalt müsste diese Abfolge doch auch identisch sein, oder nicht?!

Naja, das mit dem Bitmuster... passt glaubich nicht so. Ein VERSUCH einer Erklärung: Wenn man zwei Objekte anlegt, die den gleichen Inhalt haben, dann steht für das erste Objekt im Speicher irgendwo sowas wie
3 1.2 "Hallo"
(und so gesehen könnte man das als "Bitmuster im Speicher" interpretieren, wenn man will). An einer ANDEREN Stelle im Speicher steht AUCH
3 1.2 "Hallo"
So gesehen wären die "Bitmuster", die die Objekte beschreiben, dann gleich. Beim "normalen" equals-Vergleich werden aber (sozusagen!!!) nicht diese "Bitmuster" verglichen, sondern die STELLEN an denen diese Bitmuster im Speicher stehen. Und die sind unterschiedlich.
(Diese Aussagen sind eigentlich so unpräzise, dass man sie schon "falsch" nennen könnte, aber ich hoffe, sie machen deutlicher, was dort eigentlich abläuft)
 

jule37

Aktives Mitglied
die hashcode methode beachtet deine instanzvariablen überhaupt nicht, da sie zu java.lang.Object gehört und stets einen hashcode für ein java.lang.Object berechnet, selbiges gilt für equals... hier wird ohne überschreiben auch nur ein java.lang.Object verglichen, egal was der typ eigentlich ist.

will man also equals und hashcode vernünftig verwenden, so muss man die methoden überschreiben, was auch für z.B. entity klassen immer empfehlenswert ist.

das thema eindeutige hashcodes erzeugen ist allerdings eine kleine wissenschaft für sich und vielleicht auch eher was für mathematiker.
 

EG2009

Mitglied
Danke für die Erklärungen!

Wie müsste ich die Methode hashCode() denn überschreiben, wenn in meinem Beispiel o1 und o2 den gleichen Wert zurück liefern sollen? (Die Methode equals() ist mir erstmal egal).

Das hier funzt nicht:

Java:
		public int hashCode() {
			return titel.hashCode();
		}

Muss ich da irgendwelchen Konventionen bei der Überschreibung folgen?

Besten Dank!

GLG, Seb
 

Landei

Top Contributor
Das sollte eigentlich gehen (allerdings wird dann laenge ignoriert). Hast du die equals-Methode auch entsprechend überschrieben?
 

EG2009

Mitglied
Ich kann mir doch von 2 Objekten den gleichen Hashcode zurückgeben lassen, auch wenn diese nicht ganz equal sind, oder? Von daher muss ich in diesem Fall equals doch gar nicht überschreiben, oder sehe ich das falsch?
Ich will die Objekte ja keinem HashSet hinzufügen oder so. Dann sollte equals doch egal sein?!
 

Marco13

Top Contributor
So gesehen stimmt das: Man kann auch
Code:
public int hashCode() 
{ 
    return 0; 
}
schreiben, und braucht sich um equals so gesehen keine Gedanken zu machen. Allerdings wäre das [c]return titel.hashCode()[/c] schon besser ;) Und OB man equals nicht doch überschreiben sollte, sollte man sich auch überlegen...
 

EG2009

Mitglied
Wenn es gehen sollte, dann bräucht ich die überschriebene Hashcode Methode doch nur in meinem obigen Beispiel einfügen und sollte gleiche Hashcodes für o1 und o2 erhalten, richtig?

Die Objekte liefern aber unterschiedliche Ergebnisse zurück?!

Zumindest bei mir :autsch:.
 

Wortraum

Bekanntes Mitglied
@Marco13:
Ein Oximoron ist es vielleicht – keine Ahnung, was das ist –, ein Oxymoron ist es aber nicht. Es klingt zwar „toll“, ist aber hier falsch. Dafür ist widersprüchliches Oxymoron pleonastisch. ;)

@EG2009:
> Ich kann mir doch von 2 Objekten den gleichen Hashcode zurückgeben
> lassen, auch wenn diese nicht ganz equal sind, oder?

Ja, das kannst Du. Umgekehrt hingegen verstieße man gegen die definierte Voraussetzung, daß zwei Objekte, die im Sinne der equals-Methode gleich sind, den gleichen Streuwert zurückgeben müssen.

> Von daher muss ich in diesem Fall equals doch gar nicht
> überschreiben, oder sehe ich das falsch?

Das siehst Du richtig.

Für weitere Informationen zu diesem Thema kann ich Dir einen Blick auf diese Seite empfehlen:
AngelikaLanger.com - Implementing the hashCode() Method - Angelika Langer Training/Consulting
Wie hashCode() und equals() miteinander zusammenhängen, wird im Kapitel Der sogenannte hashCode-Contract erklärt.

> Wenn es gehen sollte, dann bräucht ich die überschriebene Hashcode
> Methode doch nur in meinem obigen Beispiel einfügen und sollte
> gleiche Hashcodes für o1 und o2 erhalten, richtig?

Beide sollten 0 zurückgeben. Wenn nicht, hast Du etwas falsch gemacht.
 

Marco13

Top Contributor
Von Tippfehlern mal abgesehen finde ich widersprüchliche Oxymora, wahre Tautologien und wahre Oxymora und widersprüchliche Tautologien eben toll :D Eigentlich wollte ich nur andeuten, dass sich Identität nicht auf den Inhalt beziehen kann. :oops:
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Ausgabe einer ArrayList ensteht nur als Hashcode, nicht als Objekt Java Basics - Anfänger-Themen 16
W Wann und warum hashcode und equals? Java Basics - Anfänger-Themen 14
S Hashcode-Berechnung + ^ Java Basics - Anfänger-Themen 2
S Interface Equals und hashCode Java Basics - Anfänger-Themen 16
L Logistiksystem Methode equals und hashcode Java Basics - Anfänger-Themen 20
W JUnit Test und HashCode Java Basics - Anfänger-Themen 14
G HashCode für Indexberechnung im Array Java Basics - Anfänger-Themen 2
E hashCode implementierung Java Basics - Anfänger-Themen 9
M hashcode Java Basics - Anfänger-Themen 3
T hashCode-Kontrakt Java Basics - Anfänger-Themen 1
Psypsy hashCode, equals und toString Java Basics - Anfänger-Themen 3
K hashCode, compareTo vs. equals Java Basics - Anfänger-Themen 3
M Wann eigene implementierte HashCode Methode zwingend erforderlich? Java Basics - Anfänger-Themen 1
T hashCode mit boolean Java Basics - Anfänger-Themen 1
M Frage zu HashCode Methode in Java Java Basics - Anfänger-Themen 7
M Hashcode als lesbarer String Java Basics - Anfänger-Themen 1
S Hashcode - Operator ^ Java Basics - Anfänger-Themen 11
G 64 Bit Hashcode erstellen aus String Java Basics - Anfänger-Themen 11
K hashCode() Java Basics - Anfänger-Themen 2
C hashCode() bei Klassen, die nicht immutable sind Java Basics - Anfänger-Themen 27
M Collections Problem bei Überschreibung von hashcode() und equals() bei Hashset-Implementierung Java Basics - Anfänger-Themen 5
H Hashcode aus Datei erzeugen Java Basics - Anfänger-Themen 7
B Hashcode Java Basics - Anfänger-Themen 25
K equals() und hashcode() überschreiben Java Basics - Anfänger-Themen 5
T Code in hashCode Java Basics - Anfänger-Themen 2
S hashCode() überschreiben Java Basics - Anfänger-Themen 13
T equals() und hashCode() Java Basics - Anfänger-Themen 7
A HashCode Überschreiben Java Basics - Anfänger-Themen 2
H Suche spezifische Eigenschaft von Object - sowas wie ".hashCode()" Java Basics - Anfänger-Themen 4
E Java hashCode equals Problem Java Basics - Anfänger-Themen 2
neurox Tutorial equals und hashCode überschreiben Java Basics - Anfänger-Themen 33
B Frage zu equals() und hashCode() Java Basics - Anfänger-Themen 28
A veränderbar kanonische Klassen: Methode equals, hashcode, serializable Java Basics - Anfänger-Themen 5
M Fehler im HashCode()! Java Basics - Anfänger-Themen 12
S equals() - hashCode() - Contract Java Basics - Anfänger-Themen 54
S HashCode überschreiben! Java Basics - Anfänger-Themen 17
D HashCode eines Objekts Java Basics - Anfänger-Themen 5
R Vergleiche mit Equals(), hashCode() und == Java Basics - Anfänger-Themen 10
M HashCode von java.io.File - Wurde die Datei geändert ? Java Basics - Anfänger-Themen 2
B Hashcode?Was ist das und wozu? Java Basics - Anfänger-Themen 2
D Array List mit Objekten sortieren Java Basics - Anfänger-Themen 2
T Kollision von 2 Objekten Java Basics - Anfänger-Themen 2
T Variable von Objekten in einer Methode überprüfen Java Basics - Anfänger-Themen 26
B Reflection ändern von Objekten in Objekten Java Basics - Anfänger-Themen 12
H Kompliziertes Sortieren einer ArrayList mit Objekten(Sortieren nach X und Y) Java Basics - Anfänger-Themen 11
T Permanentes speichern von Objekten in einer ArrayList Java Basics - Anfänger-Themen 6
N Vererbung Queue bestehend aus Superclass- und Subclass-Objekten Java Basics - Anfänger-Themen 7
B Compiler-Fehler Array aus Objekten übergeben Java Basics - Anfänger-Themen 7
YAZZ Schlüsselworte Töten von Objekten Gameover Java Basics - Anfänger-Themen 2
F Abstand zwischen zwei Objekten berechnen wie? Java Basics - Anfänger-Themen 1
districon Vergleichen von Objekten Java Basics - Anfänger-Themen 20
Zeppi OOP Array in Objekten Java Basics - Anfänger-Themen 4
LetsSebi Methode, die einen arry von objekten speichert in einer datei Java Basics - Anfänger-Themen 6
JavaNoobi Try and Catch und übergabe von Objekten Java Basics - Anfänger-Themen 2
A Klasse Menge mit Objekten der Klasse Person Java Basics - Anfänger-Themen 8
S Auf Array aus Objekten zugreifen? Java Basics - Anfänger-Themen 1
D Mit Objekten rechnen, Textfield, JavaFX, Noob Java Basics - Anfänger-Themen 8
N enum Attribut von Objekten einer Hashmap ausgeben Java Basics - Anfänger-Themen 6
A Auf Eigenschaften von Objekten anderer Klassen zugreifen Java Basics - Anfänger-Themen 5
G Problem beim Speichern von Objekten in einer Datei Java Basics - Anfänger-Themen 7
N Klassen Rekursion mit Feldern von Objekten Java Basics - Anfänger-Themen 14
D Operatoren Mit Objekten rechnen Java Basics - Anfänger-Themen 7
E Datentypen Einfügen von Objekten in eine Map Java Basics - Anfänger-Themen 2
S Pane nach speziellen Child Objekten durchsuchen Java Basics - Anfänger-Themen 3
B ID von unterschiedlichen Objekten bekommen? Java Basics - Anfänger-Themen 2
T Daten von Objekten speichern Java Basics - Anfänger-Themen 7
PaperHat Programmieraufgabe - Objekte in Objekten Java Basics - Anfänger-Themen 2
L Rechnen mit Objekten Java Basics - Anfänger-Themen 3
S werte von objekten in schleife verändern Java Basics - Anfänger-Themen 14
D Zusammenarbeit von Objekten Java Basics - Anfänger-Themen 1
Y Begrenzte Anzahl an Objekten? Java Basics - Anfänger-Themen 12
Kornblume Nulltyp eines Arrays von Objekten? Java Basics - Anfänger-Themen 10
A Frage zur Aufgabe Uhrzeit einstellen mit Objekten Java Basics - Anfänger-Themen 18
M Generische Liste aus Comparable-Objekten Java Basics - Anfänger-Themen 6
G Klassen Call by Value auch bei Objekten? Java Basics - Anfänger-Themen 2
R Verständnisfrage zu Objekten u. Übergabeparameter Java Basics - Anfänger-Themen 8
arjoopy Kapselung Übergabe von Objekten aus ArrayList Java Basics - Anfänger-Themen 4
schoenosrockos Unterschied zwischen Objekten und vererbungen Java Basics - Anfänger-Themen 1
M Speichern von Objekten - Verfügbarkeit bei erneutem Aufruf Java Basics - Anfänger-Themen 3
R Methoden Methode ruft Methode auf, ruft Methode auf (mit Objekten) Java Basics - Anfänger-Themen 4
S Serialisierung: Laden von Objekten - Risiken? Java Basics - Anfänger-Themen 4
Shizmo PriorityQueue mit Objekten Java Basics - Anfänger-Themen 10
E Instanzieren von Objekten verkürzen Java Basics - Anfänger-Themen 1
F Interaktion von Objekten verschiedener Klassen... Java Basics - Anfänger-Themen 13
D Effiziente Verwaltung der Objekten und Unterobjekten Java Basics - Anfänger-Themen 18
N Dauer zwischen zwei LocalDateTime Objekten berechnen? Java Basics - Anfänger-Themen 4
L Subklasse von ArrayList nur mit bestimmten Objekten füllen Java Basics - Anfänger-Themen 1
E Erste Schritte Gute Erklärung zu Objekten / Klassen / Methoden / Sichtbarkeiten auf Deutsch Java Basics - Anfänger-Themen 3
S Problem mit augabe von Objekten Java Basics - Anfänger-Themen 3
T Junit Mockito: Instanz von inneren erzeugten Objekten Java Basics - Anfänger-Themen 4
P Zugriff auf Felder in ArrayList Objekten Java Basics - Anfänger-Themen 2
W Was passiert mit Objekten die nicht in Objektvariablen initialisiert werden ? Java Basics - Anfänger-Themen 3
D Zugriff auf von einer anderen Klasse erstellten Objekten Java Basics - Anfänger-Themen 5
S Liste mit Objekten und Listen Java Basics - Anfänger-Themen 9
Y Gleiche Arrays aus einem Array mit Objekten Java Basics - Anfänger-Themen 5
K Min eines Arrays mit Objekten Java Basics - Anfänger-Themen 6
M Array mit Objekten lässt sich nicht auslesen Java Basics - Anfänger-Themen 10
T Statische Arrays von Objekten Java Basics - Anfänger-Themen 2
J Methoden Einfügen von Objekten nach Alphabet in ArrayList funktioniert nicht Java Basics - Anfänger-Themen 2
B Erste Schritte Anzeige von Graphics Objekten einzeln aktualisieren Java Basics - Anfänger-Themen 1

Ähnliche Java Themen

Neue Themen


Oben