HashMap zezwala na jeden klucz pusty i dowolną liczbę wartości null. Jaki jest pożytek z tego?
ConcurrentHashMap
nie obsługuje klawiszy zerowych, podczas gdy HashMap
tak.
HashMap zezwala na jeden klucz pusty i dowolną liczbę wartości null. Jaki jest pożytek z tego?
ConcurrentHashMap
nie obsługuje klawiszy zerowych, podczas gdy HashMap
tak.
Odpowiedzi:
Nie jestem pewien, o co pytasz, ale jeśli szukasz przykładu, kiedy chciałoby się użyć klucza zerowego, często używam ich na mapach, aby przedstawić domyślny przypadek (tj. Wartość, która powinna być użyta jeśli nie ma podanego klucza):
Map<A, B> foo;
A search;
B val = foo.containsKey(search) ? foo.get(search) : foo.get(null);
HashMap
obsługuje klucze o wartości null specjalnie (ponieważ nie może wywołać .hashCode()
obiektu zerowego), ale wartości null nie są niczym specjalnym, są przechowywane na mapie jak wszystko inne
HashMap
( putForNullKey
), która to obsługuje; przechowuje to w tabeli 0
B val = foo.containsKey(search) ? foo.get(search) : foo.get(null);
Myślę, że możemy po prostu wywołać metodę get na kluczu wyszukiwania, co da ten sam wynik. B val = foo.get(search);
czy mógłbyś mnie poprawić, jeśli coś jest nie tak?
val
na, null
jeśli klucz nie istnieje; mój ustawia go na dowolne null
mapy na mapie. O to właśnie chodziło, zapisuję domyślną wartość niezerową pod null
kluczem w mapie i używam jej, jeśli rzeczywisty klucz nie istnieje
Jednym z przykładów użycia null
wartości jest użycie HashMap
jako pamięci podręcznej wyników kosztownej operacji (takiej jak wywołanie zewnętrznej usługi sieciowej), która może powrócić null
.
Umieszczenie null
wartości na mapie pozwala następnie na rozróżnienie między przypadkiem, w którym operacja nie została wykonana dla danego klucza ( cache.containsKey(someKey)
zwraca false
), a gdzie operacja została wykonana, ale zwróciła null
wartość ( cache.containsKey(someKey)
zwraca true
, cache.get(someKey)
zwraca null
).
Bez null
wartości należałoby albo umieścić w pamięci podręcznej jakąś specjalną wartość, aby wskazać null
odpowiedź, albo po prostu w ogóle nie buforować tej odpowiedzi i wykonywać operację za każdym razem.
Dotychczasowe odpowiedzi uwzględniają tylko wartość posiadania null
klucza, ale pytanie dotyczy również any number of null values
.
Korzyści płynące z przechowywania wartości null
w kluczu w HashMap są takie same jak w bazach danych itp. - można zapisać rozróżnienie między wartością, która jest pusta (np. Ciąg „”), a brakiem wartości w ogóle (null) .
Oto mój jedyny nieco wymyślony przykład przypadku, w którym null
klucz może być przydatny:
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;
}
}
throw Exception
. Poza tym to nie jest tak, że próba zatrzymania nieistniejącego lub już zatrzymanego timera jest czymś, z czego dzwoniący może ogólnie odzyskać.