Was passiert mit dem ursprünglichen Wert, wenn ich denselben Schlüssel mehrmals an HashMap
die put
Methode übergebe? Und was ist, wenn sich sogar der Wert wiederholt? Ich habe keine Dokumentation dazu gefunden.
Fall 1: Überschriebene Werte für einen Schlüssel
Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","not one");
mymap.put("1","surely not one");
System.out.println(mymap.get("1"));
Wir bekommen surely not one
.
Fall 2: Doppelter Wert
Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","not one");
mymap.put("1","surely not one");
// The following line was added:
mymap.put("1","one");
System.out.println(mymap.get("1"));
Wir bekommen one
.
Aber was passiert mit den anderen Werten? Ich unterrichtete einen Schüler in Grundlagen und wurde danach gefragt. Ist das Map
wie ein Bucket, in dem auf den letzten Wert verwiesen wird (aber im Speicher)?
Antworten:
Per Definition
put
ersetzt der Befehl den vorherigen Wert, der dem angegebenen Schlüssel in der Zuordnung zugeordnet ist (konzeptionell wie eine Array-Indizierungsoperation für primitive Typen).Die Karte lässt einfach ihren Verweis auf den Wert fallen. Wenn nichts anderes einen Verweis auf das Objekt enthält, kann dieses Objekt für die Speicherbereinigung verwendet werden. Darüber hinaus gibt Java alle vorherigen Werte zurück, die dem angegebenen Schlüssel zugeordnet sind (oder
null
falls keine vorhanden sind), sodass Sie feststellen können, was vorhanden war, und bei Bedarf eine Referenz pflegen können.Weitere Informationen hier: HashMap Doc
quelle
Sie finden Ihre Antwort möglicherweise im Javadoc von Map # put (K, V) (das tatsächlich etwas zurückgibt):
Wenn Sie den zurückgegebenen Wert beim Aufruf nicht zuweisen
mymap.put("1", "a string")
, wird er einfach nicht mehr referenziert und kann daher nicht mehr gespeichert werden.quelle
null
), wie oben im Javadoc dokumentiert. Ja, das meine ich. Kann es wirklich falsch interpretiert werden?Der vorherige Wert für den Schlüssel wird gelöscht und durch den neuen ersetzt.
Wenn Sie alle Werte eines Schlüssels beibehalten möchten, können Sie Folgendes implementieren:
quelle
Es ist die Schlüssel- / Wertfunktion, und Sie könnten keinen doppelten Schlüssel für mehrere Werte haben, da Sie, wenn Sie den tatsächlichen Wert erhalten möchten, welcher der Werte zu dem
in Ihrem Beispiel eingegebenen Schlüssel gehört, wenn Sie den Wert "1" erhalten möchten, welcher Wert ist es ?!
Das ist ein Grund, für jeden Wert einen eindeutigen Schlüssel zu haben, aber Sie könnten einen Trick von Java Standard Lib haben:
und Sie könnten es auf diese Weise verwenden:
und Ergebnis der Drucke sind:
quelle
Ordnet den angegebenen Wert dem angegebenen Schlüssel in dieser Zuordnung zu. Wenn die Zuordnung zuvor eine Zuordnung für den Schlüssel enthielt, wird der alte Wert ersetzt.
quelle
Es ersetzt den vorhandenen Wert in der Karte für den jeweiligen Schlüssel. Wenn kein Schlüssel mit demselben Namen vorhanden ist, wird ein Schlüssel mit dem angegebenen Wert erstellt. z.B:
OUTPUT key = "1", value = "two"
Der vorherige Wert wird also überschrieben.
quelle
Auf Ihre Frage, ob die Karte wie ein Eimer war: Nein.
Es ist wie eine Liste mit
name=value
Paaren,name
muss aber kein String sein (kann es aber).Um ein Element abzurufen, übergeben Sie Ihren Schlüssel an die Methode get () -, die Ihnen das zugewiesene Objekt zurückgibt.
Und eine Hash- Map bedeutet, dass beim Versuch, Ihr Objekt mit der get-Methode abzurufen, das reale Objekt nicht mit dem von Ihnen angegebenen verglichen wird, da es die Liste durchlaufen und den Schlüssel vergleichen müsste Sie haben das aktuelle Element angegeben.
Dies wäre ineffizient. Unabhängig davon, woraus Ihr Objekt besteht, berechnet es stattdessen einen sogenannten Hashcode aus beiden Objekten und vergleicht diese. Es ist einfacher, zwei
int
s anstelle von zwei ganzen (möglicherweise sehr komplexen) Objekten zu vergleichen. Sie können sich den Hashcode wie eine Zusammenfassung mit einer vordefinierten Länge (int) vorstellen, daher ist er nicht eindeutig und weist Kollisionen auf. Die Regeln für den Hashcode finden Sie in der Dokumentation, zu der ich den Link eingefügt habe.Wenn Sie mehr darüber wissen möchten, sollten Sie sich Artikel über ansehen javapractices.com und technofundo.com ansehen
Grüße
quelle
Ich habe immer benutzt:
wenn ich mehrere Dinge auf einen identifizierenden Schlüssel anwenden wollte.
Sie könnten immer so etwas tun und sich ein Labyrinth schaffen!
quelle
Karten aus JDK sind nicht zum Speichern von Daten unter doppelten Schlüsseln gedacht.
Bestenfalls überschreibt der neue Wert die vorherigen.
Das schlimmste Szenario ist eine Ausnahme (z. B. wenn Sie versuchen, es als Stream zu sammeln):
Keine Duplikate:
Stream.of("one").collect(Collectors.toMap(x -> x, x -> x))
Duplizierter Stream:
Stream.of("one", "not one", "surely not one").collect(Collectors.toMap(x -> 1, x -> x))
Verwenden Sie zum Umgang mit doppelten Schlüsseln ein anderes Paket, z. B.: Https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Multimap.html
Es gibt viele andere Implementierungen, die sich mit doppelten Schlüsseln befassen. Diese werden für das Web benötigt (z. B. doppelte Cookie-Schlüssel, HTTP-Header können dieselben Felder haben, ...)
Viel Glück! :) :)
quelle
Collectors.toMap()
hat drittes Argument - Zusammenführungsfunktion. Wenn wir das letzte doppelte Element einfach überschreiben möchten :Stream.of("one", "two", "one").collect(Collectors.toMap(x -> x, x -> x, (key1, key2) -> key2))
. Link"one", "not one", "surely not one"
erzeugt keine doppelten Schlüsselfehler, da alle Zeichenfolgen unterschiedlich sind.Übrigens, wenn Sie eine Semantik wünschen, z. B. nur setzen, wenn dieser Schlüssel nicht vorhanden ist. Sie können
concurrentHashMap
mit verwendenputIfAbsent()
Funktion verwenden. Überprüfen Sie dies heraus:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html#put(K,%20V)
concurrentHashMap
ist threadsicher mit hoher Leistung, da es einen " Lock Striping " -Mechanismus verwendet, um den Durchsatz zu verbessern.quelle
Ja, dies bedeutet, dass alle 1 Schlüssel mit Wert mit dem letzten Mehrwert überschrieben werden. Hier fügen Sie "sicherlich nicht einen" hinzu, sodass nur "sicher nicht einer" angezeigt wird.
Selbst wenn Sie versuchen, mit einer Schleife anzuzeigen, werden nur ein Schlüssel und ein Wert angezeigt, die denselben Schlüssel haben.
quelle
Bedeutet, dass die Hash-Map keine Duplikate zulässt, wenn Sie die Methoden equals und hashCode () ordnungsgemäß überschrieben haben.
HashSet verwendet HashMap auch intern, siehe Quelldokument
quelle