Подтвердить что ты не робот

Java 8 Stream API для поиска уникального объекта, сопоставляющего значение свойства

Найдите совпадение объектов с значением свойства из коллекции с использованием потока Java 8.

List<Person> objects = new ArrayList<>();

Личные атрибуты → Имя, Телефон, Электронная почта.

Итерации по списку лиц и поиск подходящего адреса электронной почты. Видел, что это можно сделать через поток Java 8 легко. Но это все равно вернет коллекцию?

Пример:

List<Person> matchingObjects = objects.stream.
    filter(p -> p.email().equals("testemail")).
    collect(Collectors.toList());

Но я знаю, что он всегда будет иметь один уникальный объект. Можем ли мы что-то сделать вместо Collectors.toList, чтобы я получил фактический объект напрямую. Вместо получения списка объектов.

4b9b3361

Ответ 1

Вместо использования коллектора попробуйте использовать findFirst или findAny.

Optional<Person> matchingObject = objects.stream().
    filter(p -> p.email().equals("testemail")).
    findFirst();

Это возвращает Optional, так как список может не содержать этот объект.

Если вы уверены, что в списке всегда есть этот человек, вы можете позвонить:

Person person = matchingObject.get();

Будьте осторожны! get выдает NoSuchElementException, если значение отсутствует. Поэтому настоятельно рекомендуется сначала убедиться, что значение присутствует (либо с isPresent, либо лучше, используйте ifPresent, map, orElse или любую другую альтернативу, найденную в классе Optional).

Если вы согласны с ссылкой null, если такого человека нет, то:

Person person = matchingObject.orElse(null);

Если возможно, я бы старался избегать использования эталонного маршрута null. Другие альтернативные методы в классе Optional (ifPresent, map и т.д.) Могут решить множество вариантов использования. Я обнаружил, что использую orElse(null) только тогда, когда у меня есть существующий код, который был разработан для приема ссылок null в некоторых случаях.


У опциональных есть и другие полезные методы. Взгляните на дополнительный Javadoc.

Ответ 2

findAny & orElse

Используя findAny() и orElse():

Person matchingObject = objects.stream().
filter(p -> p.email().equals("testemail")).
findAny().orElse(null);

Останавливает поиск после обнаружения происшествия.

findAny

Optional<T> findAny()

Возвращает Optional, описывающий некоторый элемент потока, или пустой Optional, если поток пуст. Это операция короткого замыкания терминала. Поведение этой операции явно недетерминировано; Вы можете выбрать любой элемент в потоке. Это позволяет обеспечить максимальную производительность при параллельных операциях; цена заключается в том, что несколько вызовов одного и того же источника могут не возвращать один и тот же результат. (Если требуется стабильный результат, используйте вместо него findFirst().)

Ответ 3

Guava API предоставляет MoreCollectors.onlyElement(), который является сборщиком, который принимает поток , содержащий ровно один элемент, и возвращает этот элемент.

Возвращенный коллектор выбрасывает IllegalArgumentException, если поток состоит из двух или более элементов, и NoSuchElementException, если поток пуст.

Используйте приведенный ниже код для использования:

import static com.google.common.collect.MoreCollectors.onlyElement;

Person matchingPerson = objects.stream
                        .filter(p -> p.email().equals("testemail"))
                        .collect(onlyElement());