Java 8 Stream API: NPE при создании Map при значениях null

152
05 декабря 2017, 20:32

Одним моим коллегой был обнаружен баг в 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.

Как думаете, знатоки, чем можно объяснить этот феномен?

Answer 1

При заполнении результирующей мапы в реализации коллектора по умолчанию используется метод 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()));
    
READ ALSO
Не дергается функция на resize окна

Не дергается функция на resize окна

Есть проблемаКогда размер экрана меньше 1023px, то фильтры скрываются и увидеть их можно щелкнув по кнопке "Filters"

229
Аккордеон для списка JS/Jquery

Аккордеон для списка JS/Jquery

ЗдравствуйтеВопрос из разряда фантастики, но все же

278
Не работает проверка на строку JS

Не работает проверка на строку JS

Самая обычная проверка на строку, но по какой-то причине - не работает

299