#java #hashmap
#java #hashmap
Вопрос:
Традиционный код работает хорошо, как показано ниже:
Map<Integer, List<Integer>> map = new HashMap<>();
if (!map.containsKey(1)) {
map.put(1, new ArrayList<>());
}
map.get(1).add(2);
Теперь я хотел бы попробовать магию getOrDefault:
map.getOrDefault(1, new ArrayList<>()).add(2);
Но если я использую приведенную выше строку, то map.get(1)
значение равно нулю.
Почему?
Комментарии:
1. Где он выводит значение null?
2. map.getOrDefault(1, новый список массивов<>()).add(2); выведет значение null
3.
List.add
возвращает aboolean
. О каком нулевом значении мы говорим? Вы получаете исключение NullPointerException.add(2)
(что было бы невероятно)?
Ответ №1:
Потому getOrDefault
что, как следует из его названия, получает только данные с карты. Он не добавляет новый KVP на карту. Когда ключ отсутствует, значение по умолчанию, которое вы передаете getOrDefault
, возвращается, но не добавляется к карте, поэтому вы добавляете 2
в список массивов, который немедленно выбрасывается.
Другими словами, это то, что делает ваш getOrDefault
код:
ArrayList<Integer> value;
if (!map.containsKey(1)) {
value = new ArrayList<>();
} else {
value = map.get(1);
}
value.add(2);
Вы должны использовать computeIfAbsent
вместо этого. Этот метод фактически добавляет возвращаемое значение из функции в карту, если ключ отсутствует:
map.computeIfAbsent(1, x -> new ArrayList<>()).add(2);
Комментарии:
1. imo очень плохая реализация хорошей идеи: computeIfAbsent делает то, что хочет автор, но мы ничего не вычисляем, когда добавляем новый ArrayList , поэтому метод делает вещи, не связанные с тем, как он вызывается, и это создает запутанный код. Вместо этого я предпочитаю использовать традиционную версию, потому что она делает именно то, что, похоже, должно делать.
Ответ №2:
или вы могли бы сделать:
if(!map.contansKey(1)) map.put(1, new ArrayList<>());
map.get(1).add(2);
так что вы можете сохранить эти строки