Всегда ли необходима проверка на наличие ключей в HashMap?
У меня есть HashMap, скажем, 1000 записей, и я смотрю на повышение эффективности. Если к HashMap обращаются очень часто, то проверка существования ключа при каждом доступе приведет к большим издержкам. Вместо этого, если ключ отсутствует и, следовательно, возникает исключение, я могу поймать исключение. (когда я знаю, что это случится редко). Это уменьшит доступ к HashMap вдвое.
Это может быть не очень хорошая практика программирования, но это поможет мне уменьшить количество обращений. Или я что-то здесь упускаю?
[ Обновить ] У меня нет нулевых значений в HashMap.
Ответы:
Вы когда-нибудь хранили нулевое значение? Если нет, вы можете просто сделать:
В противном случае вы можете просто проверить существование, если получите возвращенное нулевое значение:
источник
get
это нормально, и вам не нужно делать два поиска, когда вам нужно это значение.if(value!=null || map.containsKey(key))
для второй части. По крайней мере, если вы хотите сделать то же самое в любом случае - без повторного кода. Это будет работать из-за короткого замыкания .Вы ничего не получите, проверив, что ключ существует. Это код
HashMap
:Просто проверьте,
get()
отличается ли возвращаемое значение отnull
.Это исходный код HashMap.
Ресурсы :
Исходный код HashMapBad oneисточник
Лучше всего использовать
containsKey
методHashMap
. Завтра кто-нибудь добавит ноль на карту. Вы должны различать наличие ключа и ключ имеет нулевое значение.источник
null
полного хранения .Вы имеете в виду, что у вас есть такой код
повсюду? Тогда вам просто нужно проверить,
map.get(key)
возвращен ли null и все. Кстати, HashMap не генерирует исключения для отсутствующих ключей, вместо этого он возвращает null. Единственный случай, когдаcontainsKey
это необходимо, когда вы храните нулевые значения, чтобы различать нулевое значение и пропущенное значение, но это обычно считается плохой практикой.источник
Просто используйте
containsKey()
для ясности. Это быстро и сохраняет код чистым и читабельным. Все делоHashMap
с в том , что ключ поиска быстро, просто убедитесь , чтоhashCode()
иequals()
правильно реализованы.источник
источник
Вы также можете использовать
computeIfAbsent()
метод вHashMap
классе.В следующем примере
map
хранится список транзакций (целых чисел), которые применены к ключу (имя банковского счета). Для того, чтобы добавить 2 сделки100
и200
доchecking_account
вы можете написать:Таким образом, вам не нужно проверять,
checking_account
существует ли ключ или нет.computeIfAbsent()
.Действительно элегантно! 👍
источник
Я обычно использую идиому
Это означает, что вы попадаете на карту только дважды, если отсутствует ключ
источник
источник
Ответ Джона Скита хорошо обращается к двум сценариям (карта со
null
значением и неnull
значением) эффективным способом.О количестве записей и проблем эффективности, я хотел бы добавить кое-что.
Карта с 1000 записей не является огромной картой.
А также карта с 5.000 или 10.000 записей.
Map
предназначены для быстрого поиска с такими размерами.Теперь предполагается, что
hashCode()
ключи карты обеспечивают хорошее распределение.Если вы можете использовать в
Integer
качестве типа ключа, сделайте это.Его
hashCode()
метод очень эффективен, поскольку столкновения невозможны для уникальныхint
значений:Если для ключа вам нужно использовать другой встроенный тип, как,
String
например, который часто используется вMap
, у вас могут быть некоторые коллизии, но от 1 тысячи до нескольких тысяч объектов вMap
, у вас должно быть очень мало таких какString.hashCode()
метод обеспечивает хорошее распределение.Если вы используете пользовательский тип, переопределите
hashCode()
иequals()
правильно и убедитесь, что в целом этоhashCode()
обеспечивает справедливое распределение.Вы можете обратиться к пункту 9
Java Effective
ссылки.Вот пост, который подробно описывает путь.
источник