"Vielleicht ist das Problem nicht, dass uns nichts stört, sondern dass wir es stören."
Bmargulies
3
In Guava, Google-Sammlungen, erlauben viele Klassen keine Null und der Grund dafür ist, dass 95% der Fälle keine Null benötigen und Fehler darstellen können, die möglicherweise schwer zu finden sind.
Stivlo
Seltsam ist, dass ConcurrentHashMapdies keine Nullschlüssel unterstützt, während dies der HashMapFall ist.
Codepleb
2
Nur HashMap erlaubt null :)
Subhashis
Antworten:
126
Ich bin mir nicht sicher, was Sie fragen, aber wenn Sie nach einem Beispiel suchen, wann man einen Nullschlüssel verwenden möchte, verwende ich sie häufig in Karten, um den Standardfall darzustellen (dh den Wert, der verwendet werden sollte wenn ein bestimmter Schlüssel nicht vorhanden ist):
Map<A, B> foo;
A search;
B val = foo.containsKey(search)? foo.get(search): foo.get(null);
HashMapbehandelt Nullschlüssel speziell (da es kein .hashCode()Nullobjekt aufrufen kann ), aber Nullwerte sind nichts Besonderes, sie werden wie alles andere in der Karte gespeichert
Wenn also .hashCode () für null nicht möglich ist, wer entscheidet dann, in welchen Wagen der Nullschlüssel eingegeben wird?
Pacerier
26
@Pacerier In HashMap( putForNullKey) gibt es eine spezielle Methode , die damit umgeht . es speichert es in Tabelle 0
Michael Mrozek
1
@MichaelMrozek Ihre letzte Zeile B val = foo.containsKey(search) ? foo.get(search) : foo.get(null);Ich denke, wir können einfach get-Methode auf Suchschlüssel aufrufen, die das gleiche Ergebnis haben wird. B val = foo.get(search);Könnten Sie mich bitte korrigieren, wenn ich etwas falsch mache?
Dheerajraaj
6
@ dheeraj92 Ihr Code wird auf gesetzt val, nullwenn der Schlüssel nicht vorhanden ist. meins setzt es auf die nullKarten in der Karte. Das war der Punkt, ich speichere einen Standardwert ungleich Null am nullSchlüssel in der Karte und verwende ihn, wenn der tatsächliche Schlüssel nicht existiert
Michael Mrozek
28
Ein Beispiel wäre das Modellieren von Bäumen. Wenn Sie eine HashMap verwenden, um eine Baumstruktur darzustellen, bei der der Schlüssel das übergeordnete Element und der Wert die Liste der untergeordneten Elemente ist, sind die Werte für den nullSchlüssel die Stammknoten.
Ein Beispiel für die Verwendung von nullWerten ist die Verwendung von a HashMapals Cache für Ergebnisse einer teuren Operation (z. B. eines Aufrufs eines externen Webdienstes), die möglicherweise zurückgegeben wird null.
Wenn Sie einen nullWert in die Zuordnung einfügen, können Sie zwischen dem Fall unterscheiden, in dem die Operation für einen bestimmten Schlüssel nicht ausgeführt wurde ( cache.containsKey(someKey)Rückgabe false), und dem Fall, in dem die Operation ausgeführt wurde, aber einen nullWert zurückgegeben hat ( cache.containsKey(someKey)Rückgabe true, cache.get(someKey)Rückgabe null).
Ohne nullWerte müssten Sie entweder einen speziellen Wert in den Cache einfügen, um eine nullAntwort anzuzeigen , oder diese Antwort einfach überhaupt nicht zwischenspeichern und die Operation jedes Mal ausführen.
Die bisherigen Antworten berücksichtigen nur den Wert eines nullSchlüssels, aber die Frage fragt auch nach any number of null values.
Der Vorteil des Speicherns des Werts nullfür einen Schlüssel in einer HashMap ist der gleiche wie in Datenbanken usw. - Sie können einen Unterschied zwischen einem leeren Wert (z. B. Zeichenfolge "") und einem Wert (null) aufzeichnen. .
Hier ist mein nur ein wenig erfundenes Beispiel für einen Fall, in dem der nullSchlüssel nützlich sein kann:
publicclassTimer{privatestaticfinalLogger LOG =Logger.getLogger(Timer.class);privatestaticfinalMap<String,Long> START_TIMES =newHashMap<String,Long>();publicstaticsynchronizedvoid start(){long now =System.currentTimeMillis();if(START_TIMES.containsKey(null)){
LOG.warn("Anonymous timer was started twice without being stopped; previous timer has run for "+(now - START_TIMES.get(null).longValue())+"ms");}
START_TIMES.put(null, now);}publicstaticsynchronizedlong stop(){if(! START_TIMES.containsKey(null)){return0;}return printTimer("Anonymous", START_TIMES.remove(null),System.currentTimeMillis());}publicstaticsynchronizedvoid start(String name){long now =System.currentTimeMillis();if(START_TIMES.containsKey(name)){
LOG.warn(name +" timer was started twice without being stopped; previous timer has run for "+(now - START_TIMES.get(name).longValue())+"ms");}
START_TIMES.put(name, now);}publicstaticsynchronizedlong stop(String name){if(! START_TIMES.containsKey(name)){return0;}return printTimer(name, START_TIMES.remove(name),System.currentTimeMillis());}privatestaticlong printTimer(String name,long start,long end){
LOG.info(name +" timer ran for "+(end - start)+"ms");return end - start;}}
Wenn Sie versuchen, einen nicht vorhandenen oder bereits gestoppten Timer zu stoppen, sollte dies ein Fehler sein, der nicht ignoriert wird.
Fund Monica Klage
@QPaysTaxes - Hängt von Ihrer Absicht ab. Wenn Sie ein leichtes Dienstprogramm wünschen, das einfach zu verwenden ist, möchten Sie im Allgemeinen nicht in throw Exceptionder Nähe sein. Außerdem ist es nicht so, als würde der Anrufer im Allgemeinen versuchen, einen nicht vorhandenen oder bereits gestoppten Timer zu stoppen.
aroth
1
Ein weiteres Beispiel: Ich verwende es, um Daten nach Datum zu gruppieren. Einige Daten haben jedoch kein Datum. Ich kann es mit dem Header "NoDate" gruppieren
Ein Nullschlüssel kann auch hilfreich sein, wenn die Karte Daten für die Auswahl der Benutzeroberfläche speichert, wobei der Kartenschlüssel ein Bean-Feld darstellt.
Ein entsprechender Nullfeldwert würde beispielsweise in der UI-Auswahl als "(bitte auswählen)" dargestellt.
ConcurrentHashMap
dies keine Nullschlüssel unterstützt, während dies derHashMap
Fall ist.Antworten:
Ich bin mir nicht sicher, was Sie fragen, aber wenn Sie nach einem Beispiel suchen, wann man einen Nullschlüssel verwenden möchte, verwende ich sie häufig in Karten, um den Standardfall darzustellen (dh den Wert, der verwendet werden sollte wenn ein bestimmter Schlüssel nicht vorhanden ist):
HashMap
behandelt Nullschlüssel speziell (da es kein.hashCode()
Nullobjekt aufrufen kann ), aber Nullwerte sind nichts Besonderes, sie werden wie alles andere in der Karte gespeichertquelle
HashMap
(putForNullKey
) gibt es eine spezielle Methode , die damit umgeht . es speichert es in Tabelle 0B val = foo.containsKey(search) ? foo.get(search) : foo.get(null);
Ich denke, wir können einfach get-Methode auf Suchschlüssel aufrufen, die das gleiche Ergebnis haben wird.B val = foo.get(search);
Könnten Sie mich bitte korrigieren, wenn ich etwas falsch mache?val
,null
wenn der Schlüssel nicht vorhanden ist. meins setzt es auf dienull
Karten in der Karte. Das war der Punkt, ich speichere einen Standardwert ungleich Null amnull
Schlüssel in der Karte und verwende ihn, wenn der tatsächliche Schlüssel nicht existiertEin Beispiel wäre das Modellieren von Bäumen. Wenn Sie eine HashMap verwenden, um eine Baumstruktur darzustellen, bei der der Schlüssel das übergeordnete Element und der Wert die Liste der untergeordneten Elemente ist, sind die Werte für den
null
Schlüssel die Stammknoten.quelle
Ein Beispiel für die Verwendung von
null
Werten ist die Verwendung von aHashMap
als Cache für Ergebnisse einer teuren Operation (z. B. eines Aufrufs eines externen Webdienstes), die möglicherweise zurückgegeben wirdnull
.Wenn Sie einen
null
Wert in die Zuordnung einfügen, können Sie zwischen dem Fall unterscheiden, in dem die Operation für einen bestimmten Schlüssel nicht ausgeführt wurde (cache.containsKey(someKey)
Rückgabefalse
), und dem Fall, in dem die Operation ausgeführt wurde, aber einennull
Wert zurückgegeben hat (cache.containsKey(someKey)
Rückgabetrue
,cache.get(someKey)
Rückgabenull
).Ohne
null
Werte müssten Sie entweder einen speziellen Wert in den Cache einfügen, um einenull
Antwort anzuzeigen , oder diese Antwort einfach überhaupt nicht zwischenspeichern und die Operation jedes Mal ausführen.quelle
Die bisherigen Antworten berücksichtigen nur den Wert eines
null
Schlüssels, aber die Frage fragt auch nachany number of null values
.Der Vorteil des Speicherns des Werts
null
für einen Schlüssel in einer HashMap ist der gleiche wie in Datenbanken usw. - Sie können einen Unterschied zwischen einem leeren Wert (z. B. Zeichenfolge "") und einem Wert (null) aufzeichnen. .quelle
Hier ist mein nur ein wenig erfundenes Beispiel für einen Fall, in dem der
null
Schlüssel nützlich sein kann:quelle
throw Exception
der Nähe sein. Außerdem ist es nicht so, als würde der Anrufer im Allgemeinen versuchen, einen nicht vorhandenen oder bereits gestoppten Timer zu stoppen.Ein weiteres Beispiel: Ich verwende es, um Daten nach Datum zu gruppieren. Einige Daten haben jedoch kein Datum. Ich kann es mit dem Header "NoDate" gruppieren
quelle
Ein Nullschlüssel kann auch hilfreich sein, wenn die Karte Daten für die Auswahl der Benutzeroberfläche speichert, wobei der Kartenschlüssel ein Bean-Feld darstellt.
Ein entsprechender Nullfeldwert würde beispielsweise in der UI-Auswahl als "(bitte auswählen)" dargestellt.
quelle