Java 8 Stream API, aby znaleźć unikalny obiekt pasujący do wartości właściwości
Znajdź obiekt pasujący do wartości właściwości z kolekcji za pomocą Java 8 Stream.
List<Person> objects = new ArrayList<>();
Atrybuty Osoby - > Imię, telefon, Email.
Iteracja poprzez listę osób i znaleźć obiekt pasujący e-mail. Widziałem, że można to zrobić za pomocą strumienia Java 8 łatwo. Ale to i tak zwróci kolekcję?
Ex:
List<Person> matchingObjects = objects.stream.
filter(p -> p.email().equals("testemail")).
collect(Collectors.toList());
Ale wiem, że zawsze będzie miał JEDEN unikalny przedmiot. Czy możemy zrobić coś zamiast Collectors.toList
tak, że mam rzeczywiste obiekt bezpośrednio.Zamiast otrzymywać listę obiektów. 3 answers
Zamiast używać kolektora spróbuj użyć findFirst
lub findAny
.
Optional<Person> matchingObject = objects.stream().
filter(p -> p.email().equals("testemail")).
findFirst();
Zwraca Optional
, ponieważ lista może nie zawierać tego obiektu.
Jeśli jesteś pewien, że lista zawsze zawiera tę osobę, możesz zadzwonić:
Person person = matchingObject.get();
Bądź jednak ostrożny! get
rzuca NoSuchElementException
jeśli nie ma wartości. Dlatego zaleca się, aby najpierw upewnić się, że wartość jest obecna (albo z isPresent
lub lepiej, Użyj ifPresent
, map
, orElse
lub którąkolwiek z innych alternatyw Znalezione w klasie Optional
).
Jeśli nie masz nic przeciwko referencji null
Jeśli nie ma takiej osoby, to:
Person person = matchingObject.orElse(null);
Jeśli to możliwe, starałbym się jednak unikać drogi odniesienia null
. Inne metody alternatywne w klasie opcjonalnej (ifPresent
, map
itp.) może rozwiązać wiele przypadków użycia. Gdzie znalazłem się za pomocą orElse(null)
jest tylko wtedy, gdy mam istniejący kod, który został zaprojektowany do przyjmowania null
odniesienia w niektórych przypadkach.
Opcje mają inne użyteczne metody też. Spójrz na opcjonalny javadoc.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-28 09:48:38
findAny
& orElse
Za pomocą findAny()
oraz orElse()
:
Person matchingObject = objects.stream().
filter(p -> p.email().equals("testemail")).
findAny().orElse(null);
Przestaje szukać po znalezieniu zdarzenia.
findAny
Optional<T> findAny()
Zwraca opcjonalny opisujący jakiś element strumienia lub opcjonalny pusty, jeśli strumień jest pusty. Jest to operacja zwarcia terminala. Zachowanie tej operacji jest jawnie nieeterministyczne; można dowolnie wybrać dowolny element w strumieniu. Ma to pozwolić na maksymalną wydajność w operacjach równoległych; koszt polega na tym, że wielokrotne wywołania na tym samym źródle mogą nie zwrócić tego samego wyniku. (Jeśli pożądany jest stabilny wynik, należy użyć funkcji findFirst ().)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55
Guava API zapewnia Więcej kolektorów.onlyElement (), który jest kolektorem, który pobiera strumień zawierający dokładnie jeden element i zwraca ten element .
Zwracany kolektor rzuca an IllegalArgumentException
jeśli strumień składa się z dwóch lub więcej elementów , a NoSuchElementException
jeśli strumień jest pusty .
Patrz poniższy kod do użycia:
import static com.google.common.collect.MoreCollectors.onlyElement;
Person matchingPerson = objects.stream
.filter(p -> p.email().equals("testemail"))
.collect(onlyElement());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-15 02:46:03