Извлечение списка свойств объекта через Java Stream API

Пройдите тест, узнайте какой профессии подходите

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

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

Java 8 Streams позволяет извлекать список свойств объектов, преобразуя каждый объект к его свойству. Процесс состоит в обращении к .stream() в вашем списке, применении .map() для доступа к свойству и сборе результатов через .collect(Collectors.toList()).

Возьмём пример для класса Person с методом getName:

Java
Скопировать код
List<String> names = peopleList.stream()
                               .map(Person::getName)
                               .collect(Collectors.toList());

Основной посыл: мы используем .map() для преобразования объектов в их свойства и .collect(), чтобы собрать результаты.

Кинга Идем в IT: пошаговый план для смены профессии

Когда использовать map, а когда flatMap

Импользуйте map для преобразования элементов потока. Если требуется обработать коллекцию, которая находится внутри каждого объекта, и получить один общий поток, тогда вам подойдёт flatMap.

Пример с использованием flatMap: Вы хотите получить имена всех друзей из списка друзей каждого объекта Person:

Java
Скопировать код
List<String> friendNames = peopleList.stream()
                                     .flatMap(p -> p.getFriends().stream())
                                     .map(Person::getName)
                                     .collect(Collectors.toList());

Не забывайте: flatMap идеален для обработки вложенных коллекций.

Работа с комплексными свойствами

Если требуется извлечь сложные свойства, лямбда-выражения станут неоценимым помощником, позволяя проводить тонкую настройку над элементами потока.

Пример: Вы хотите получить список адресов в нижнем регистре:

Java
Скопировать код
List<String> addressList = peopleList.stream()
                                     .map(Person::getAddress)
                                     .map(String::toLowerCase)
                                     .collect(Collectors.toList());

Важно помнить: Для поддержания чистоты и удобочитаемости кода всегда старайтесь использовать ссылки на методы для основных преобразований.

Бережное использование Optional свойств

Тип Optional в Java 8 позволяет безопасно обращаться к свойствам, значение которых может оказаться null, и предотвращает появление NullPointerException. Безопасное использование Optional подразумевает сочетание методов filter и map.

Пример: Извлечение псевдонимов, если они присутствуют:

Java
Скопировать код
List<String> nicknames = peopleList.stream()
                                   .map(Person::getNickname)     // Optional<String>
                                   .filter(Optional::isPresent)  // Java обеспечивает безопасность
                                   .map(Optional::get)           // Безопасно получаем значение
                                   .collect(Collectors.toList());

Запомните: Работа с Optional повысит надежность вашего кода на Java.

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

Представьте, что вы отбираете зелёные яблоки (🍏) из корзины с различными фруктами, используя специальную машину для сортировки фруктов (🤖):

Markdown
Скопировать код
Корзина 🧺: [🍏, 🍎, 🍌, 🍏, 🍇, 🍏, 🍓]
Машина 🤖: Stream().filter(apple::isGreen).collect(toList());

После того, как закончится сортировка:

Markdown
Скопировать код
Список Зелёных Яблок 🍏: [🍏, 🍏, 🍏]
// Похоже, Stream API отлично справляется с отбором зелёных яблок!

Итак, создание списка свойств — это как отбор Зелёных Яблок в вашу корзину 🍏➡️🧺

Не просто сборщик, а настоящий мастер

Метод toList() – лишь верхушка айсберга возможностей сборщиков в Java 8. Разберитесь в множестве сборщиков, доступных для агрегирования элементов, таких как toSet или joining.

Пример: Имеется список имён людей, и вы хотите получить одну строку, состоящую из этих имён:

Java
Скопировать код
String names = peopleList.stream()
                         .map(Person::getName)
                         .collect(Collectors.joining(", "));
// И вот перед вами итоговый результат – высокое искусство красивого кода

Совет: Попробуйте разные сборщики, типа toSet(). Они непременно вам понравятся, особенно когда требуются только уникальные элементы.

Как обрабатывать исключения в потоках

Если операции в потоке могут вызвать исключения, важно аккуратно обернуть их в лямбда-выражения, чтобы сохранить последовательность и читаемость кода.

Пример: Чтение файлов может привести к IOException:

Java
Скопировать код
List<Path> paths = ...;
List<String> lines = paths.stream()
                          .flatMap(p -> {
                              try {
                                  return Files.lines(p);
                              } catch (IOException e) {
                                  throw new UncheckedIOException(e);
                              }
                          })
                          .collect(Collectors.toList());

Совет: Соблюдайте осторожность, превращая проверяемые исключения в непроверяемые, не забывая о корректности работы программы.

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

  1. java.util.stream (Java Платформа SE 8) — документация по API Java 8 Stream для углубленного изучения.
  2. Учебник Java 8 STREAMS – YouTube — видеоматериалы по Stream API с наглядными примерами.
  3. Just a moment... — обучающее руководство от Baeldung по Java 8 Streams, комбинирующее теорию и практику.
  4. javascript – "'length' in Object(obj)" Как это работает в js? – Stack Overflow — обсуждение, которое косвенно может помочь осознать доступ к свойствам и работу с рефлексией, несмотря на то, что контекст обсуждения – не Java.
  5. Error 404 – InfoQ — статьи об инновационных способах обработки данных в Java 8, хотя ссылка, похоже, уже неактивна.