Что произойдет, если в Stream Java встретится null элемент?

«Что произойдет, если в Stream Java встретится null элемент?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Возникнет NullPointerException при выполнении операции, которая пытается вызвать метод у null.

Пример проблемы:

List<String> list = Arrays.asList("Java", null, "Stream");

// NPE в map()
list.stream()
    .map(String::toUpperCase)  // String::toUpperCase на null → NPE
    .forEach(System.out::println);

// NPE в sorted()
list.stream()
    .sorted()                  // Сравнение null с объектом → NPE
    .forEach(System.out::println);

Решения:

  1. Фильтрация null (рекомендуется):

    list.stream()
    .filter(Objects::nonNull)  // Удаляем null
    .map(String::toUpperCase)
    .forEach(System.out::println);
  2. Обработка в map():

    list.stream()
    .map(str -> str != null ? str.toUpperCase() : "DEFAULT")
    .forEach(System.out::println);
  3. Использование Optional:

    list.stream()
    .map(Optional::ofNullable)
    .filter(Optional::isPresent)
    .map(Optional::get)
    .map(String::toUpperCase)
    .forEach(System.out::println);

Особые случаи:

  • Примитивные стримы не допускают null:

    List<Integer> numbers = Arrays.asList(1, null, 3);
    numbers.stream()
    .mapToInt(Integer::intValue)  // NPE на null
    .sum();
  • Collectors.toMap() с null значениями:

    Map<String, String> map = list.stream()
    .collect(Collectors.toMap(
        Function.identity(), 
        String::toUpperCase  // NPE если значение null
    ));

Best practices:

  1. Фильтруйте null как можно раньше в цепочке
  2. Документируйте, допускает ли ваш метод null в Stream
  3. Используйте @Nullable/@NonNull аннотации
  4. Для nullable полей используйте flatMap с Optional:
    
    class Person {
    private String name; // может быть null
    }

persons.stream() .map(Person::getName) .flatMap(Optional::ofNullable) .forEach(System.out::println);