Фильтрация null значений из списка в Java8: обработка исключений
Быстрый ответ
Вы можете отсеивать значения null, используя комбинацию Objects::nonNull и Stream#filter:
List<String> noNulls = list.stream().filter(Objects::nonNull).collect(Collectors.toList());
В списке noNulls присутствуют только те элементы, которые не равны null.
Теперь давайте более подробно рассмотрим использование лямбда-выражений и потоков Java 8 для обработки значений, отличных от null.

Работа со сложными условиями: объединение фильтров
Для фильтрации null и применения дополнительных критериев, можно объединить несколько фильтров:
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:
List<String> carNames = cars.stream()
.filter(Objects::nonNull)
.filter(car -> car.getName() != null) // Проверяется наличие имени у автомобиля
.map(Car::getName) // Преобразование в список имен
.collect(Collectors.toList());
Итак, полученный список будет включать имена всех автомобилей, исключив тех, у которых имя не определено.
Обработка потенциально null значений в коллекциях
Если есть риск, что список может быть равен null, применяйте Optional.ofNullable и orElseGet:
List<String> safeList = Optional.ofNullable(list)
.orElseGet(Collections::emptyList) // Для исключения рисков упадка программы
.stream()
.filter(Objects::nonNull)
.collect(Collectors.toList());
Это позволит исключить проблемы при обработке списков.
Продвинутые методы фильтрации строк
При работе со строками вы можете прибегнуть к помощи класса StringUtils:
List<String> nonEmptyNames = names.stream()
.filter(StringUtils::isNotBlank) // Оставляем только непустые строки
.collect(Collectors.toList());
Данный подход использует класс StringUtils из библиотеки Apache Commons Lang для отсеивания пустых и null строк.
Визуализация
Представьте, что вы ищете сокровища, среди которых находятся ценные (ненулевые) и бесполезные (null) предметы:
Ваши находки: [💎, null, 📀, null, 🏺]
Лямбда-функция отфильтрует и оставит только ценные предметы:
yourItems.stream().filter(Objects::nonNull).collect(Collectors.toList());
В итоге, пройдут только драгоценные камни (💎), золотые диски (📀) и антикварные вазы (🏺):
До: [💎, null, 📀, null, 🏺]
После: [💎, 📀, 🏺]
Значения null будут исключены!
Обработка больших данных с помощью потоков
Используйте потоки для эффективной работы с большими наборами данных:
- Ленивость операций: Операторы, такие как
filter, выполняются только при необходимости. - Сокращение вычислений: Некоторые операции, например,
findAny, могут завершиться ещё до обработки всей коллекции. - Параллельная обработка: Параллельные потоки позволяют эффективно использовать многоядерные процессоры.
Защита вложенных свойств от null значений
Следуйте нижеуказанному подходу для защиты свойств от null значений:
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.
Полезные материалы
- Stream (Java Platform SE 8 ) — Документация Java 8 по методу
Stream.filter(). - Java SE 8: Lambda Quick Start — Краткое введение в лямбда-выражения от Oracle.
- Java 8: performance of Streams vs Collections – Stack Overflow — Обсуждение производительности потоков в Java 8 на Stack Overflow.
- 26 Reasons Why Using Optional Correctly Is Not Optional – DZone Java — Статья о правильном использовании
Optional.


