Фильтрация 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
.