Фильтрация null значений из списка в Java8: обработка исключений

Пройдите тест, узнайте какой профессии подходите и получите бесплатную карьерную консультацию
В конце подарим скидку до 55% на обучение
Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Вы можете отсеивать значения null, используя комбинацию Objects::nonNull и Stream#filter:

Java
Скопировать код
List<String> noNulls = list.stream().filter(Objects::nonNull).collect(Collectors.toList());

В списке noNulls присутствуют только те элементы, которые не равны null.

Теперь давайте более подробно рассмотрим использование лямбда-выражений и потоков Java 8 для обработки значений, отличных от null.

Работа со сложными условиями: объединение фильтров

Для фильтрации null и применения дополнительных критериев, можно объединить несколько фильтров:

Java
Скопировать код
List<Car> filteredCars = cars.stream()
    .filter(Objects::nonNull) // Исключаем значения null
    .filter(car -> "Red".equals(car.getColor())) // Оставляем только красные автомобили
    .collect(Collectors.toList());

Таким образом, полученный список автомобилей будет содержать только красные машины, исключая значения null.

Использование ссылок на методы при работе со списками

Если вам кажется избыточным писать obj -> obj != null, воспользуйтесь ссылкой на метод (Objects::nonNull).

Проверка атрибутов для предотвращения NullPointerException

При обращении к атрибутам объектов следует быть внимательным, чтобы избежать NullPointerException:

Java
Скопировать код
List<String> carNames = cars.stream()
    .filter(Objects::nonNull)
    .filter(car -> car.getName() != null) // Проверяется наличие имени у автомобиля
    .map(Car::getName) // Преобразование в список имен
    .collect(Collectors.toList());

Итак, полученный список будет включать имена всех автомобилей, исключив тех, у которых имя не определено.

Обработка потенциально null значений в коллекциях

Если есть риск, что список может быть равен null, применяйте Optional.ofNullable и orElseGet:

Java
Скопировать код
List<String> safeList = Optional.ofNullable(list)
    .orElseGet(Collections::emptyList) // Для исключения рисков упадка программы
    .stream()
    .filter(Objects::nonNull)
    .collect(Collectors.toList());

Это позволит исключить проблемы при обработке списков.

Продвинутые методы фильтрации строк

При работе со строками вы можете прибегнуть к помощи класса StringUtils:

Java
Скопировать код
List<String> nonEmptyNames = names.stream()
    .filter(StringUtils::isNotBlank) // Оставляем только непустые строки
    .collect(Collectors.toList());

Данный подход использует класс StringUtils из библиотеки Apache Commons Lang для отсеивания пустых и null строк.

Визуализация

Представьте, что вы ищете сокровища, среди которых находятся ценные (ненулевые) и бесполезные (null) предметы:

Markdown
Скопировать код
Ваши находки: [💎, null, 📀, null, 🏺]

Лямбда-функция отфильтрует и оставит только ценные предметы:

Java
Скопировать код
yourItems.stream().filter(Objects::nonNull).collect(Collectors.toList());

В итоге, пройдут только драгоценные камни (💎), золотые диски (📀) и антикварные вазы (🏺):

Markdown
Скопировать код
До: [💎, null, 📀, null, 🏺]
После: [💎, 📀, 🏺]

Значения null будут исключены!

Обработка больших данных с помощью потоков

Используйте потоки для эффективной работы с большими наборами данных:

  • Ленивость операций: Операторы, такие как filter, выполняются только при необходимости.
  • Сокращение вычислений: Некоторые операции, например, findAny, могут завершиться ещё до обработки всей коллекции.
  • Параллельная обработка: Параллельные потоки позволяют эффективно использовать многоядерные процессоры.

Защита вложенных свойств от null значений

Следуйте нижеуказанному подходу для защиты свойств от null значений:

Java
Скопировать код
List<String> ownerNames = cars.stream()
    .filter(car -> car.getOwner() != null && car.getOwner().getName() != null) // Проверяем дважды
    .map(car -> car.getOwner().getName())
    .collect(Collectors.toList());

Перед обработкой убедитесь, что свойство Owner объекта и его атрибут Name не являются null.

Кодинг-Сага: Цепочка операций с использованием потоков

Применяйте всю мощь filter, map и collect для создания конвейера обработки данных:

  • Filter: Отсеките неподходящие элементы.
  • Map: Преобразуйте элементы в соответствии с заданной логикой.
  • Collect: Соберите результаты в финальную коллекцию.

Создавайте эффективный код с использованием лямбда-выражений

  • Упрощайте: Объединяйте все условия в одном фильтре.
  • Минимизируйте количество вызовов: Сокращайте использование методов в потоковых операциях.
  • Используйте подходящие инструменты: Для решения специфических задач используйте такие библиотеки, как Apache Commons Lang или Google Guava.

Полезные материалы

  1. Stream (Java Platform SE 8 ) — Документация Java 8 по методу Stream.filter().
  2. Java SE 8: Lambda Quick Start — Краткое введение в лямбда-выражения от Oracle.
  3. Java 8: performance of Streams vs Collections – Stack Overflow — Обсуждение производительности потоков в Java 8 на Stack Overflow.
  4. 26 Reasons Why Using Optional Correctly Is Not Optional – DZone Java — Статья о правильном использовании Optional.