HashMap допускает один нулевой ключ и любое количество нулевых значений. Какая от этого польза?
ConcurrentHashMapон не поддерживает нулевые ключи, а HashMapподдерживает.
HashMap допускает один нулевой ключ и любое количество нулевых значений. Какая от этого польза?
ConcurrentHashMapон не поддерживает нулевые ключи, а HashMapподдерживает.
Ответы:
Я не уверен в том, что вы спрашиваете, но если вы ищете пример того, когда можно было бы использовать нулевой ключ, я часто использую их в картах для представления случая по умолчанию (т.е. значения, которое следует использовать если данный ключ отсутствует):
Map<A, B> foo;
A search;
B val = foo.containsKey(search) ? foo.get(search) : foo.get(null);
HashMapобрабатывает нулевые ключи специально (поскольку он не может вызывать .hashCode()нулевой объект), но нулевые значения не являются чем-то особенным, они хранятся на карте, как и все остальное
HashMap( putForNullKey) , который обрабатывает его; он хранит его в таблице 0
B val = foo.containsKey(search) ? foo.get(search) : foo.get(null);я думаю, мы можем просто вызвать метод get для ключа поиска, который будет иметь такой же результат. B val = foo.get(search);не могли бы вы поправить меня, если я ошибаюсь?
valна, nullесли ключ не существует; мой устанавливает его для любых nullкарт на карте. В том-то и дело, я сохраняю ненулевое значение по умолчанию в nullключе на карте и использую его, если фактический ключ не существует,
Одним из примеров использования null значений является использование a HashMapв качестве кеша для результатов дорогостоящей операции (например, вызова внешней веб-службы), которая может возвращаться null.
nullЗатем размещение значения на карте позволяет вам различать случай, когда операция не была выполнена для данного ключа ( cache.containsKey(someKey)возврат false), и случай , когда операция была выполнена, но вернула nullзначение ( 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;
}
}
throw Exception. Кроме того, это не похоже на попытку остановить несуществующий или уже остановленный таймер - это то, от чего вызывающий обычно может восстановиться.
Нулевой ключ также может быть полезен, когда на карте хранятся данные для выбора пользовательского интерфейса, где ключ карты представляет собой поле компонента.
Соответствующее значение пустого поля, например, будет представлено как «(пожалуйста, выберите)» в выборе пользовательского интерфейса.