Ist es möglich, HashMap
für alle Schlüssel, die nicht im Set enthalten sind, einen Standardwert zurückzugeben?
java
dictionary
hashmap
Larry
quelle
quelle
getOrDefault()
LinkAntworten:
[Aktualisieren]
Wie von anderen Antworten und Kommentatoren angemerkt, können Sie ab Java 8 einfach aufrufen
Map#getOrDefault(...)
.[Original]
Es gibt keine Map-Implementierung, die dies genau tut, aber es wäre trivial, eine eigene zu implementieren, indem Sie HashMap erweitern:
quelle
(v == null)
bis anpassen ,(v == null && !this.containsKey(k))
falls sie absichtlich einennull
Wert hinzufügen . Ich weiß, dies ist nur ein Eckfall, aber der Autor kann darauf stoßen.!this.containsValue(null)
. Dies unterscheidet sich geringfügig von!this.containsKey(k)
. DiecontainsValue
Lösung schlägt fehl, wenn einem anderen Schlüssel explizit der Wert "zugewiesen" wurdenull
. Zum Beispiel: Wirdmap = new HashMap(); map.put(k1, null); V v = map.get(k2);
in diesem Fallv
nochnull
richtig sein?Verwenden Sie in Java 8 Map.getOrDefault . Der Schlüssel und der Wert müssen zurückgegeben werden, wenn kein passender Schlüssel gefunden wird.
quelle
getOrDefault
ist sehr schön, erfordert aber bei jedem Zugriff auf die Karte die Standarddefinition. Das einmalige Definieren eines Standardwerts hätte auch Lesbarkeitsvorteile beim Erstellen einer statischen Wertekarte.private static String get(Map map, String s) { return map.getOrDefault(s, "Error"); }
Verwenden Sie die DefaultedMap von Commons, wenn Sie das Rad nicht neu erfinden möchten , z.
Sie können auch eine vorhandene Karte übergeben, wenn Sie nicht erst für die Erstellung der Karte verantwortlich sind.
quelle
Java 8 hat eine nette computeIfAbsent- Standardmethode für die
Map
Schnittstelle eingeführt, die faul berechneten Wert speichert und so den Kartenvertrag nicht bricht:Herkunft: http://blog.javabien.net/2014/02/20/loadingcache-in-java-8-without-guava/
Disclamer: Diese Antwort stimmt nicht genau mit dem überein, was OP gefragt hat, kann jedoch in einigen Fällen nützlich sein, wenn der Schlüsseltitel begrenzt ist und das Zwischenspeichern verschiedener Werte rentabel wäre. Es sollte nicht im umgekehrten Fall mit vielen Schlüsseln und demselben Standardwert verwendet werden, da dies unnötig Speicherplatz verschwenden würde.
quelle
Können Sie nicht einfach eine statische Methode erstellen, die genau dies tut?
quelle
Sie können einfach eine neue Klasse erstellen, die HashMap erbt, und die Methode getDefault hinzufügen. Hier ist ein Beispielcode:
Ich denke, dass Sie die Methode get (K key) in Ihrer Implementierung nicht überschreiben sollten, da Ed Staub in seinem Kommentar Gründe angegeben hat und Sie den Vertrag über die Map-Schnittstelle brechen werden (dies kann möglicherweise zu schwer zu findenden Gründen führen Bugs).
quelle
get
Methode nicht zu überschreiben . Auf der anderen Seite erlaubt Ihre Lösung nicht, die Klasse über eine Schnittstelle zu verwenden, was häufig der Fall ist.Verwenden:
quelle
Dies geschieht standardmäßig. Es kehrt zurück
null
.quelle
HashMap
nur für diese Funktionalität eine Unterklasse zu bilden, wenn diesnull
vollkommen in Ordnung ist.NullObject
Muster verwenden oder keine Nullprüfungen in Ihrem Code verteilen möchten - ein Wunsch, den ich vollständig verstehe.Auf Java 8+
quelle
Ich fand die LazyMap sehr hilfreich.
Auf diese Weise können Sie Folgendes tun:
Der Aufruf zum
get
Erstellen eines Standardwerts für den angegebenen Schlüssel. Sie geben an, wie der Standardwert mit dem Factory-Argument an erstellt werden sollLazyMap.lazyMap(map, factory)
. Im obigen Beispiel wird die KarteAtomicInteger
mit dem Wert 0 auf eine neue Karte initialisiert .quelle
List<String>
: Wenn ich die akzeptierte Antwort verwende, riskiere ich, für jeden neuen Schlüssel dieselbe Liste zu verwenden, anstatt (sagen wir) einenew ArrayList<String>()
aus einer Fabrik.Nicht direkt, aber Sie können die Klasse erweitern, um ihre get-Methode zu ändern. Hier ist ein gebrauchsfertiges Beispiel: http://www.java2s.com/Code/Java/Collections-Data-Structure/ExtendedVersionofjavautilHashMapthatprovidesanextendedgetmethodaccpetingadefaultvalue.htm
quelle
Anwendungsbeispiel:
quelle
Ich musste die Ergebnisse lesen, die von einem Server in JSON zurückgegeben wurden, auf dem ich nicht garantieren konnte, dass die Felder vorhanden sind. Ich verwende die Klasse org.json.simple.JSONObject, die von HashMap abgeleitet ist. Hier sind einige Hilfsfunktionen, die ich verwendet habe:
quelle
Berücksichtigen Sie in gemischten Java / Kotlin-Projekten auch Kotlins Map.withDefault .
quelle