Одним моим коллегой был обнаружен баг в Stream API
: если создавать Map из stream() при помощи .collect(Collectors.toMap())
, то всё валится с NPE
при значениях null
(не ключах).
header.set(Stream.of(Utils.<String, Object>entry("description", status.getDescription())).
collect(utils.entriesToMap()));
Если status.getDescription() == null
, то NPE.
Как думаете, знатоки, чем можно объяснить этот феномен?
При заполнении результирующей мапы в реализации коллектора по умолчанию используется метод merge
(JDK 1.8b112 java.util.stream.Collectors:1319
):
BiConsumer<M, T> accumulator
= (map, element) -> map.merge(keyMapper.apply(element),
valueMapper.apply(element), mergeFunction);
А если заглянуть в реализацию этого метода в классе HashMap
, то можно увидеть следующее (java.util.HashMap:1223
):
if (value == null)
throw new NullPointerException();
Если не указывать явно, то при использовании Collectors.toMap()
, всё собирается в экземпляр класса HashMap
.
Варианты решения:
HashMap
и TreeMap
к таким не относятся, как и все, которые наследуются от интерфейса Map
, не переопределяя метод merge
, потому что в дефолтной реализации тоже есть строка Objects.requireNonNull(value)
)самим написать метод добавления новых элементов в мапу и не использовать merge
:
.collect(
HashMap::new,
(map, entry) -> map.put(entry.getKey(), entry.getValue()),
HashMap::putAll
);
использовать forEach
с сайд-эффектом (не надо так, используйте лучше второй вариант):
Map<K, V> newMap = ...
stream.forEach(e -> newMap.put(e.getKey(), e.getValue()));
Виртуальный выделенный сервер (VDS) становится отличным выбором
Есть проблемаКогда размер экрана меньше 1023px, то фильтры скрываются и увидеть их можно щелкнув по кнопке "Filters"
Самая обычная проверка на строку, но по какой-то причине - не работает