# HashCode überschreiben!



## Skull (23. Mrz 2009)

Hallo, habe bereits erfolgreich die equals Methode für eines meiner Objekte umgeschrieben, bei HashCode habe ich aber so meine Probleme.

Mein Object hat 3 Strings, die gleich sein müssen, damit equals gleich ist. Wie erzeuge ich nun eine Hashfunktion, die für zwei Objekte, die die gleichen 3 Strings haben den gleichen HashCode liefert?


----------



## andre111 (23. Mrz 2009)

z.B.
return string1.hashCode() ^ string2.hashCode() ^ string3.hashCode();


----------



## Wildcard (23. Mrz 2009)

Zum Beispiel so:
[HIGHLIGHT="Java"]int hashcode = string1.hashCode() + string2.hashCode() +string3.hashCode()[/HIGHLIGHT]


----------



## Ark (23. Mrz 2009)

Dir sollte hoffentlich aufgefallen sein, dass du hashCode() in Abhängigkeit von nur _einem_ Objekt beschreiben musst.

Ich bin spontan für etwas dieser Art:
[HIGHLIGHT="Java"]return str1.hashCode() ^ str2.hashCode() ^ str3.hashCode();[/HIGHLIGHT]
Diese Funktion ist aber nur dann zu gebrauchen, wenn die Reihenfolge/Zuordnung keine Rolle spielt. Wenn sie doch eine Rolle spielt, würde ich eine andere Hashfunktion versuchen.

Ark

EDIT: Hui, das ging aber schnell. xD


----------



## Skull (23. Mrz 2009)

Funktioniert leider nicht. Bekomme immernoch false, wenn ich das ganze in ner HashMap teste.


----------



## Ark (23. Mrz 2009)

Skull hat gesagt.:


> Funktioniert leider nicht. Bekomme immernoch false, wenn ich das ganze in ner HashMap teste.


Zeig doch bitte den Code.  Welche Methode liefert diesen Wert wann?

Ark


----------



## Skull (23. Mrz 2009)

Myoject mo = new Myobject("A","B","C", "D");
Myoject mo2 = new Myobject("A","B","C", "Q");
HashMap hm = new HashMap();
hm.put(mo)
System.out.println(hm.containsKey(mo2));

D habe ich bei equals als irrelevant deklariert. Es geht also nur um die ersten drei Einträge


abgesehen davon ist die Reihenfolge auch nicht egal, es müssen die einzelnen Strings in der richtigen Reihenfolge sein. (ABC) != (ACB)

EDIT: Mein Fehler geht, aber Reihenfolge ist noch das Problem.


----------



## Skull (23. Mrz 2009)

Wie wäre es hiermit?

String neu;

neu = String1 + String2+ String3;

return neu.hashCode();

müsste doch gehen oder nicht?


----------



## Ark (23. Mrz 2009)

Was du suchst, ist nicht zufälligerweise ein HashSet, oder? Und dass Myobject und Myobject2 zwei verschiedene Klassen sind und es deshalb zwei verschiedene hashCode()-Methoden zu implementieren gibt, ist dir auch klar? Und dass zwei verschiedene Typen in einem Set selten Sinn ergeben, weißt du auch, ja? Was bitte ist denn ein Myobject, und was ist ein Myobject2? Und du bist dir sicher, die Sache mit Klassen und Objekten richtig verstanden zu haben?

Seit Tiger gibt's auch typsichere Collections, da wäre so etwas, was du hier zeigst, nur sehr bedingt durchführbar ...

Ark


----------



## Skull (23. Mrz 2009)

Es werden Objekte zwischen entfernten Endgeräten ausgetauscht. Ich habe zur Übertragung der Objekte nur die Möglichkeit diese per String zu übertragen, deshalb mache ich aus einem Objekt per toString einen String und nach der Übertragung wieder ein Objekt. Da nun das gleiche Objekt mehrfach übertragen wird, habe ich logischerweise jedesmal nach dem parsen ein neues Objekt und möchte prüfen ob es schon eine Instanz in der HashMap gibt, wenn ja dann mache dies, wenn nein, dann dies. In der Hashmap liegt auch nur eine Instanz....

Macht doch Sinn?!


----------



## Ebenius (23. Mrz 2009)

equals() sollte, von dem abgesehen was Ark schreibt, nicht true zurückgeben, wenn die Objekte nicht den selben Typ haben.

Ebenius


----------



## Skull (23. Mrz 2009)

Sie haben den selben Typ  und ich prüfe das auch per instanceof!


Edit: Ah jetzt verstehe ich eure Anmerkungen. habe bei dem vereinfachten Beispiel nen Fehler gemacht MyObject2 gibts nicht . Habs mal korrigiert.


----------



## Marco13 (23. Mrz 2009)

```
Myoject mo = new Myobject("A","B","C", "D");
Myoject mo2 = new Myobject("A","B","C", "Q");

System.out.println("hashCode0 "+mo.hashCode());
System.out.println("hashCode1 "+mo2.hashCode());
System.out.println("equal? "+mo.equals(mo2));
```
--> Ausgabe?


----------



## Ark (23. Mrz 2009)

Skull hat gesagt.:


> Edit: Ah jetzt verstehe ich eure Anmerkungen. habe bei dem vereinfachten Beispiel nen Fehler gemacht MyObject2 gibts nicht . Habs mal korrigiert.


Ich nehme mal an, du hast noch einen Fehler gemacht, denn put() ist in HashMap mit zwei Parametern definiert. 

Mich würde gerade zu sehr interessieren, wie der Code aussieht, denn aktuell kann ich nicht wirklich einen Fehler feststellen.

Ark

PS: Mann, das geht ja hier im Minutentakt.


----------



## Skull (23. Mrz 2009)

Mein reales Beispiel ist etwas länger, deshalb habe ich hier eben schnell ein vereinfachtes hingeklickt. Das Forum hier ist aber leider nicht Eclipse *g*, weshalb ich hier schnell mal einige Fehler reingehauen habe (unter anderem auch das "put", ja *g*).

Die von dir vorgeschlagene Variante funktioniert, ich habe aber jetzt meine Variante genommen, da wie gesagt auch die Belegung der einzelnen Strings (also die Reihenfolge) eine Rolle spielt. Klappts jetzt alles wunderbar.

Danke an alle.


----------



## Ebenius (24. Mrz 2009)

Ich würde dafür nicht die Strings aneinanderhängen, weil das sehr teuer ist. Wenn die Reihenfolge für Dich wichtig ist, dann sollte einfach sowas funktionieren: [HIGHLIGHT="Java"]return 53 * s1.hashCode() + 17 * s2.hashCode() + s3.hashCode();[/HIGHLIGHT]

Ebenius


----------



## FArt (24. Mrz 2009)

Hm, worum geht es eigentlich?
Jede halbwegs sinnvolle IDE generiert doch den Käse, und zwar so dass es sinnvoll ist, konsistent ist und funktioniert.


```
@Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof Blubb)) return false;

    Blubb blubb = (Blubb) o;

    if (!str1.equals(blubb.str1)) return false;
    if (!str2.equals(blubb.str2)) return false;
    if (!str3.equals(blubb.str3)) return false;

    return true;
  }

  @Override
  public int hashCode() {
    int result = str1.hashCode();
    result = 31 * result + str2.hashCode();
    result = 31 * result + str3.hashCode();
    return result;
  }
```


----------



## SchonWiederFred (24. Mrz 2009)

Skull hat gesagt.:


> Funktioniert leider nicht. Bekomme immernoch false, wenn ich das ganze in ner HashMap teste.


Meine Glaskugel sagt, dass Du "hashCode" falsch geschrieben hast, z.B. "hashcode" oder "HashCode".


----------

