2010-05-31 2 views
73

HashMap ermöglicht einen Nullschlüssel und eine beliebige Anzahl von Nullwerten. Was nützt es?Was nützt es, einer HashMap in Java einen Null-Schlüssel oder -Wert hinzuzufügen?

+11

"Vielleicht ist das Problem nicht, dass uns nichts stört, sondern dass wir es belästigen." – bmargulies

+3

In Guava, google collections, lassen viele Klassen keine Null zu, und der Grund dafür ist, dass 95% der Fälle keine null benötigen und sie möglicherweise schwer zu findende Fehler darstellen. – stivlo

+0

Seltsam ist, dass 'ConcurrentHashMap' keine Null-Schlüssel unterstützt, während' HashMap' dies tut. – codepleb

Antwort

106

Ich bin nicht positiv, was Sie fragen, aber wenn Sie nach einem Beispiel suchen, wenn man einen Nullschlüssel verwenden möchte, verwende ich sie oft in Karten, um den Standardfall (dh den Wert) darzustellen das sollte verwendet werden, 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); 

HashMap Griffe null Schlüssel speziell (da es nicht .hashCode() auf ein null-Objekt) aufrufen können, aber nULL-Werte sind nichts besonderes, sie in der Karte wie alles andere gespeichert

+3

Also, wenn .hashCode() ist nicht möglich auf Null, wer entscheidet, welche Wagen den Null-Schlüssel eingeben wird? – Pacerier

+22

@Pacerier Es gibt eine spezielle Methode in 'HashMap' (' putForNullKey'), die es handhabt; Es speichert es in Tabelle 0 –

+0

@MichaelMrozek Ihre letzte Zeile 'B val = foo.containsKey (suchen)? foo.get (search): foo.get (null); ' Ich denke, wir können einfach Methode auf Suchschlüssel aufrufen, die das gleiche Ergebnis haben wird. 'B val = foo.get (Suche);' Könnten Sie mich bitte korrigieren, wenn ich etwas falsch mache? – dheerajraaj

25

Ein Beispiel wäre für die Modellierung von Bäumen. Wenn Sie eine HashMap verwenden, um eine Baumstruktur darzustellen, wobei der Schlüssel der übergeordnete und der Wert eine Liste von untergeordneten Elementen ist, wären die Werte für den Schlüssel null die Stammknoten.

2

Hier ist mein nur-etwas-konstruiertes Beispiel für einen Fall, in dem der null Schlüssel nützlich sein kann:

public class Timer { 
    private static final Logger LOG = Logger.getLogger(Timer.class); 
    private static final Map<String, Long> START_TIMES = new HashMap<String, Long>(); 

    public static synchronized void 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); 
    } 

    public static synchronized long stop() { 
     if (! START_TIMES.containsKey(null)) { 
      return 0; 
     } 

     return printTimer("Anonymous", START_TIMES.remove(null), System.currentTimeMillis()); 
    } 

    public static synchronized void 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); 
    } 

    public static synchronized long stop(String name) { 
     if (! START_TIMES.containsKey(name)) { 
      return 0; 
     } 

     return printTimer(name, START_TIMES.remove(name), System.currentTimeMillis()); 
    } 

    private static long printTimer(String name, long start, long end) { 
     LOG.info(name + " timer ran for " + (end - start) + "ms"); 
     return end - start; 
    } 
} 
+0

Wenn du versuchst, einen nicht existierenden Timer zu stoppen, oder einen, der gestoppt wurde schon, das sollte ein Fehler sein, nicht ignoriert. –

+0

@QPaysTaxes - Hängt von Ihrer Absicht ab. Wenn Sie ein leichtgewichtiges Dienstprogramm haben möchten, das einfach zu verwenden ist, möchten Sie normalerweise nicht "Exception" herumwerfen. Außerdem ist es nicht so, als ob der Aufrufer im Allgemeinen wiederherstellen kann, wenn er versucht, einen nicht vorhandenen oder bereits gestoppten Timer zu stoppen. – aroth

1

Ein anderes Beispiel: Ich habe es zu Gruppe Daten nach dem Datum verwenden. Aber einige Daten haben kein Datum. Ich kann es Gruppe mit dem Header „NoDate“

3

Die Antworten bisher nur den Wert betrachten haben einen null Schlüssel, aber die Frage fragt auch nach any number of null values.

Der Vorteil des Speicherns des Werts null gegen einen Schlüssel in einer HashMap ist derselbe wie in Datenbanken usw. - Sie können einen Unterschied zwischen einem leeren Wert (z. B. string "") und keinem Wert aufzeichnen überhaupt (null).

6

Ein Beispiel für die Verwendung für nullWerte ist, wenn für die Ergebnisse einer teueren Operation (wie beispielsweise einen Anruf zu einem externen Web-Service) ein HashMap als Cache verwendet, die null zurückkehren.

einen null Wert in der Karte Putting ermöglicht dann Sie zwischen dem Fall zu unterscheiden, wo der Betrieb für einen bestimmten Schlüssel (cache.containsKey(someKey) kehrt false), und wo der Betrieb aber wieder einen null Wert wurde durchgeführt hat (cache.containsKey(someKey) nicht durchgeführt worden gibt true, cache.get(someKey) zurück null).

Ohne null Werte müssten Sie entweder einen speziellen Wert in den Cache setzen, um eine null Antwort anzuzeigen, oder diese Antwort einfach nicht zwischenspeichern und die Operation jedes Mal ausführen.

0

Ein Null-Schlüssel kann auch hilfreich sein, wenn die Karte Daten für UI-Auswahlen speichert, in denen der Map-Schlüssel ein Bean-Feld darstellt.

Ein entsprechender Nullfeldwert würde beispielsweise in der Benutzeroberflächenauswahl als "(bitte auswählen)" dargestellt.

Verwandte Themen