Какой смысл добавлять нулевой ключ или значение в хэш-карту в Java?
HashMap позволяет один нулевой ключ и любое количество нулевых значений. Какая от этого польза?
7 ответов:
Я не уверен, что вы спрашиваете, но если вы ищете пример того, когда можно было бы использовать нулевой ключ, я часто использую их в картах для представления случая по умолчанию (т. е. значение, которое должно использоваться, если данный ключ отсутствует):
Map<A, B> foo; A search; B val = foo.containsKey(search) ? foo.get(search) : foo.get(null);
HashMap
обрабатывает нулевые ключи специально (так как он не может вызвать.hashCode()
на нулевом объекте), но нулевые значения не являются чем-то особенным, они хранятся на карте, как и все остальное
один пример был бы для моделирования деревьев. Если вы используете хэш-карту для представления древовидной структуры, где ключ является родительским, а значение-списком дочерних элементов, то значения для
null
ключ будет корневыми узлами.
пример использования
null
значения при использованииHashMap
в качестве кэша для результатов дорогостоящей операции (например, вызова внешней веб-службы), которая может возвращатьnull
.поставить
null
значение в карте тогда позволяет различать случай, когда операция не была выполнена для данного ключа (cache.containsKey(someKey)
возвращаетfalse
), и где операция была выполнена, но возвращена anull
значение (cache.containsKey(someKey)
возвращаетtrue
,cache.get(someKey)
возвращаетnull
).без
null
значения, вы должны были бы либо поставить какое-то специальное значение в кэше, чтобы указатьnull
ответ, или просто не кэшировать этот ответ вообще и выполнять операцию каждый раз.
ответы до сих пор только считают ценность иметь
null
ключ, но вопрос также спрашивает оany number of null values
.преимущество хранения значения
null
против ключа в HashMap то же самое, что и в базах данных и т. д. - Вы можете записать различие между наличием пустого значения (например, строки"") и отсутствием значения вообще (null).
вот мой единственный-несколько-надуманный пример случая, когда
null
ключ может быть полезной: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; } }