Wie zu verwenden-Sets als Schlüssel in Java-Maps
Habe ich eine Karte, die verwendet eine Reihe für den Schlüssel geben, wie diese:
Map<Set<Thing>, Val> map;
Wenn ich die Abfrage anzeigen.containsKey(myBunchOfThings), gibt false zurück, und ich verstehe nicht, warum. Ich kann Durchlaufen und jeden Schlüssel in das keyset und stellen Sie sicher, es ist ein Schlüssel, der (1) den gleichen hashCode, und (2) gleich() myBunchOfThings.
System.out.println(map.containsKey(myBunchOfThings)); //false.
for (Set<Thing> k : map.keySet()) {
if (k.hashCode() == myBunchOfThings.hashCode() && k.equals(myBunchOfThings) {
System.out.println("Fail at life."); //it prints this.
}
}
Kann ich nur grundlegend missverstehen der Vertrag für containsKey? Ist es ein Geheimnis, um die Verwendung von sets (oder allgemein, Sammlungen) als Schlüssel zu den Karten?
InformationsquelleAutor der Frage Gabe Johnson | 2010-03-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Schlüssel sollte nicht mutiert, während in der verwendeten Karte. Die
Map
java-doc sagt:Wusste ich, dass dieses Problem, aber nie machte Sie den test, bis jetzt. Ich aufwändige dann ein bisschen mehr:
Nach
key2
mutiert ist, die Karte nicht enthalten, es nicht mehr. Wir könnten denken, dass die Karte "Indizes" sind die Daten, wenn es Hinzugefügt, und wir würden dann erwarten, dass es enthält immer noch den key2-Klon (Linie markiert mit*
). Aber lustig genug, das ist nicht der Fall.So, da die java-doc sagt, der Schlüssel sollte nicht sein, sonst mutiert das Verhalten ist unbekannter. Zeitraum.
Ich denke, das ist, was passiert in Ihrem Fall.
InformationsquelleAutor der Antwort ewernli
Sollten Sie versuchen zu verwenden, unveränderliche Typen als Schlüssel für
Map
s. Sammlungen und sets sind in der Regel sehr leicht veränderlich, so sind in der Regel eine schlechte Idee, auf diese Weise.Wenn Sie viele Schlüssel-Werte als
Map
Schlüssel, den Sie verwenden sollten, eine Klasse Umsetzung für diesen Zweck entwickelt wurde, wie die Apache Commons CollectionsMultiKey
.Wenn Sie wirklich müssen eine Reihe oder Sammlung, wie ein Schlüssel, es unveränderlich (
Collections.unmodifiableSet(...)
) und dann nicht halten eine Referenz auf das veränderliche Objekt sichern.Eine weitere Schwierigkeit, die mit der Verwendung von Sammlungen als Schlüssel ist, dass Sie konstruiert werden könnte, in einer anderen Reihenfolge. Nur eine geordnete Sammlung wird eine hohe wahrscheinlich-Haube passenden. Zum Beispiel, wenn Sie eine sequenziell geordnete
ArrayList
aber konstruieren Sie die Liste in einer anderen Weise beim zweiten mal wird es nicht mit dem Schlüssel übereinstimmen, - der hash-code und die Reihenfolge der Werte ist unterschiedlich.BEARBEITEN: ich stehe korrigiert, diese Aussage unter, die Sie nie gehabt zu verwenden, Legen Sie für eine ket. Ich habe gerade gelesen, ein Teil der hashCode-Implementierung in AbstractHashSet. Dieser verwendet eine einfache Summe aller Werte ist also nicht abhängig von der Reihenfolge. Equals prüft auch, ob ein Satz enthält alle Werte, die in dem anderen Satz. Dies aber immer noch wahr ist, mit anderen Arten von Collections in Java (ArrayList Reihenfolge nicht egal).
Wenn Sie Ihre Sammlung ist eigentlich ein
HashSet
die Schaffung von Ordnung bedeuten kann als gut. In der Tat eine hash-verwaltet-Sammlung jeder Art werden noch problematischer, als Kapazitäten, die Veränderungen auslösen, einen Neuaufbau der gesamten Sammlung, die die Reihenfolge der Elemente. Denke der Kollisionen der Hash-Werte gespeichert sind, in der Reihenfolge der Kollision auftreten (eine einfache verknüpfte Kette aller Elemente, wo die transformierten hash-Wert ist der gleiche).InformationsquelleAutor der Antwort Kevin Brock
Haben, ändern Sie die Menge nach dem einsetzen? Wenn ja, ist es möglich, das set habe sortiert in eine andere Periode als die, die Sie suchen. Bei der Iteration, findet Ihr set, da sieht es in der ganzen Karte.
Glaube ich, dass der Vertrag für HashMap-Staaten Sie sind nicht erlaubt zu ändern, den hashcode für Objekte, die als Schlüssel verwendet,
InformationsquelleAutor der Antwort Jorn
Sind Sie vorbei an den genauen Satz (dem Satz, den Sie finden wollen), wenn der Vergleich für den Schlüssel?
InformationsquelleAutor der Antwort Leniel Maccaferri