Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
ich arbeite jetzt eigentlich schon eine Weile (im Studium) mit Java, aber ich denke mein Problem passt wohl immer noch hier am besten rein.
Also, ich schreibe ein Programm, in dem ein Objekt über eine HashMap verfügt, die es selber mit Werten füllt. Diese Map wird von einer anderen Klasse benutzt. Aber sämtliche Operationen, die in dieser Liste nach Keys suchen geben definitiv falsche Ergebnisse raus.
Mein erster verdacht war, dass die equals() der Objekte in der Map fehlerhaft ist, schließlich habe ich die selber geschrieben. Aber lokale tests (in der Klasse, die die HashMap operationen auszuführen versucht) ergaben, dass diese sehr wohl funktionieren.
Hier kurz als Ausschnitt der kritische Teil des Codes:
Code:
Public Class Testing{
Examples.init(); // Initialisieren des Inhalts der Hashmap
HashMap map=Examples.getMap(); // Verweis auf die Map in dieser Klasse, ausgabe aller Werte würde ergeben, dass ein Pair a,b enthalten ist.
Pair test1=new Pair("a","b"); // Erstellen eines in der Map existenten Eintrag in dieser Klasse
System.out.println(map.containsKey(test1)); // Ausgabe ist: false =/
}
Nein, habe ich nicht. Die habe ich auch nie benutzt.
Ich erinnere mich dunkel an einen Zusammenhang mit equals.. ich sollte vielleicht mal die API durchstöbern ^^
Ürigens mit deinem Code oben kann ich rein _gar nichts_ anfangen.
Wenn also das Problem noch nicht gelöst ist bitte möglichst den ganzen Code hier posten und am besten so zusammen gekürzt, dass der Code möglichst wenig ist aber dein Problem immernoch widerspiegeln kann...
Also aus Erfahrung meine ich mich zu erinnern, dass du zwangsweise hashCode überschreiben musst.
Sonst wirst du kein equals == true bekommen. Ansonsten ja, mehr und ein KSCB wäre gut
Es wird meines Wissens nicht zwangsweise gefordert, dass hashCode() überschrieben wird
sobald equals() überschrieben wird.
Es mag eine Schwachstelle von Java sein ...!?
Es handelt sich nur um eine Empfehlung.
Es gibt sogenannte contracts, einen für equals() und einen hashCode() und da wird
deklariert, dass zwischen equals() und hashCode eine bestimmter sinnvoller bzw. praktischer Zusammenhang besteht.
Wenn equals nicht überschrieben wird, dann sollte diese eigentlich immer [c]false[/c] liefern (ausser die Referenz ist wirklich gleich).
Wird hashCode nicht überschrieben (und der Code darum gleich!?), dann ist der Rechenaufwand für die Map AFAIK grösser, da er noch per equals vergleichen muss. Oder gibt hashCode immer was anderes? Die API sagt mir da irgendwie nichts wirklich nützliches. Auf alle Fälle suboptimal.
Wenn equals überschrieben wird MUSS auch hashcode überschrieben werden. Sonst kann das zu größeren Problemen führen eben bzgl. Objekten die in HashMaps o.ä. verschwinden.
Für die zusammenarbeit zwischen Equals und HashCode gilt:
HashCode MUSS immer den selben HashCode für Objekte die Equals sind zurück geben. Sind Objekte unterschiedlich KANN aber muss nicht der HashCode anders sein.
D.h. auf hashCode immer 0 zurück zu geben ist valide! Aber ineffizient, aber aus anderen Gründen.
Achtung! Es gibt weitere Regeln für die Implementierung von Equals!
Jeder der diese Regeln nicht befolgt ist selber Schuld wenn bei ihm Elemente verloren gehen .
@Shulyn
da wird nichts spannendes stehen, nur u.a. auch bereits einmal new Pair("a","b") eingefügt,
das wird als Kopie erstellt nicht gefunden weil eben standardmäßig anderer Object-Hashcode,
kein großes Geheimnis dabei
... nur u.a. auch bereits einmal new Pair("a","b") eingefügt,
das wird als Kopie erstellt nicht gefunden weil eben standardmäßig anderer Object-Hashcode,
kein großes Geheimnis dabei
Die API hat mir bei meinem Problem nicht wirklich geholfen, da ich nach einer konreten implementirung für hashCode() gesucht habe, die verrät ja nicht einmal, wie die defaultbelegung von hasCode() ist =/
Google wusste das allerdings schon: Hier. Da steht, wie man hashCode() sinnvoll überschreibt.
wie man angesichts von Lehrbüchern und solchen Links immer wieder lesen muss dass die API irgendwas ausreichend erklärt,
wundert mich auch oft
es gibt Beispiele wie Klasse Pattern zu RegEx, wo ich auch direkt nachschlage, aber das sind Ausnahmen
Eclipse weiss es auch die Felder sind von mir, die Methode generiert:
Java:
private String foo;
private int bar;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + bar;
result = prime * result + (foo == null ? 0 : foo.hashCode());
return result;
}
(This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)
okay, is not required, aber normalerweise die Speicheradresse, zumindest aus meiner Erfahrung bei Sun und openJDK. Aber stimmt schon, einiges muß man sich selber zusammenlesen.