Как обновить значение по ключу в хэш-карте?
У меня есть проблема с обновлением значения в HashMap<String, Integer>
в Java.
Как я могу обновить (увеличить) значение типа Integer для строкового ключа каждый раз, когда я нахожу этот ключ?
Можно было бы удалить существующую пару и вставить новую, но это создаст лишние затраты на производительность. Другой вариант — просто вставить новую пару, и старая будет заменена.
Однако, в последнем случае, что произойдет, если возникнет коллизия хеш-кодов с новым ключом, который я пытаюсь вставить? Правильное поведение хеш-таблицы должно заключаться в том, чтобы назначить новое место для него или создать список в текущем бакете.
Как правильно реализовать инкремент значения для существующего ключа с учетом возможных коллизий?
5 ответ(ов)
Ваш код выглядит вполне корректно:
map.put(key, map.get(key) + 1);
Он обновляет значение для существующей пары ключ-значение. Обратите внимание, что здесь используется автозапаковка (auto-boxing). С помощью map.get(key)
вы получаете значение, соответствующее указанному ключу, а затем можете обновить его в соответствии с вашим требованием. В данном случае я увеличиваю значение на 1.
Способ в Java 8:
Вы можете использовать метод computeIfPresent
, предоставив ему функцию отображения, которая будет вызвана для вычисления нового значения на основе существующего.
Например:
Map<String, Integer> words = new HashMap<>();
words.put("hello", 3);
words.put("world", 4);
words.computeIfPresent("hello", (k, v) -> v + 1);
System.out.println(words.get("hello"));
В качестве альтернативы вы можете использовать метод merge
, где 1 — это значение по умолчанию, а функция увеличивает существующее значение на 1:
words.merge("hello", 1, Integer::sum);
Кроме того, существует множество других полезных методов, таких как putIfAbsent
, getOrDefault
, forEach
и т.д.
В данном коде происходит следующее: метод put
вставляет ключ key
в хэш-карту и устанавливает его значение равным текущему значению по этому ключу, увеличенному на 1. Если ключ уже существует в хэш-карте, то метод put
заменит его текущее значение на новое. Если ключ не существует, он будет создан с начальным значением равным 1.
Таким образом, весь процесс можно разложить на шаги:
hashmap.get(key)
— получает текущее значение по ключуkey
из хэш-карты. Если ключ отсутствует, возвращаетсяnull
.hashmap.get(key) + 1
— если значение неnull
, прибавляется 1 к текущему значению; если значениеnull
, то произойдет ошибка, поэтому важно убедиться, что ключ существует перед этой операцией.hashmap.put(key, ...)
— установит новое значение для ключаkey
.
Если хотите избежать ошибки при обращении к null
, рекомендуется добавить проверку перед этой строкой. Например:
hashmap.put(key, hashmap.getOrDefault(key, 0) + 1);
В этом случае, если ключ отсутствует, в качестве значения будет использовано 0, и результатом станет правильная инкрементация.
Однострочное решение:
map.put(key, map.containsKey(key) ? map.get(key) + 1 : 1);
Этот код использует метод put
для добавления значения в map
. Он проверяет, существует ли уже ключ key
в map
. Если да, то увеличивает его значение на 1, иначе устанавливает значение 1 для нового ключа.
Вы можете увеличить значение по ключу следующим образом, но необходимо проверить его существование, чтобы избежать выбрасывания исключения NullPointerException:
if (!map.containsKey(key)) {
p.put(key, 1);
} else {
p.put(key, map.get(key) + 1);
}
Обратите внимание, что я исправил метод getKey()
на get(key)
, так как он должен извлекать значение по указанному ключу.
Инициализация ArrayList в одну строчку
Что значит "Не удалось найти или загрузить основной класс"?
Как установить Java 8 на Mac
Почему в RecyclerView отсутствует onItemClickListener()?
Что значит 'synchronized'?