HashCode überschreiben!

Status
Nicht offen für weitere Antworten.

Skull

Aktives Mitglied
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?
 
Zum Beispiel so:
[HIGHLIGHT="Java"]int hashcode = string1.hashCode() + string2.hashCode() +string3.hashCode()[/HIGHLIGHT]
 
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
 
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.
 
Zuletzt bearbeitet:
Wie wäre es hiermit?

String neu;

neu = String1 + String2+ String3;

return neu.hashCode();

müsste doch gehen oder nicht?
 
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
 
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?!
 
equals() sollte, von dem abgesehen was Ark schreibt, nicht true zurückgeben, wenn die Objekte nicht den selben Typ haben.

Ebenius
 
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.
 
Zuletzt bearbeitet:
Code:
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?
 
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. 🙂
 
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.
 
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
 
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.

Code:
  @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;
  }
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben