Właśnie zacząłem grać z lambdami Java 8 i próbuję zaimplementować niektóre rzeczy, do których jestem przyzwyczajony w językach funkcjonalnych.
Na przykład większość języków funkcjonalnych ma funkcję wyszukiwania, która działa na sekwencjach lub listach zwracających pierwszy element, dla którego jest predykat true
. Jedyny sposób, w jaki mogę to osiągnąć w Javie 8, to:
lst.stream()
.filter(x -> x > 5)
.findFirst()
Wydaje mi się to jednak nieefektywne, ponieważ filtr skanuje całą listę, przynajmniej według mojego zrozumienia (co może być błędne). Czy jest lepszy sposób?
java
java-8
java-stream
siki
źródło
źródło
Odpowiedzi:
Nie, filtr nie skanuje całego strumienia. Jest to operacja pośrednia, która zwraca leniwy strumień (właściwie wszystkie operacje pośrednie zwracają leniwy strumień). Aby Cię przekonać, możesz po prostu wykonać następujący test:
Które wyjścia:
Widzisz, że tylko dwa pierwsze elementy strumienia są faktycznie przetwarzane.
Możesz więc zastosować swoje podejście, które jest całkowicie w porządku.
źródło
get();
tutaj, ponieważ wiem, które wartości przesyłam do potoku strumienia, a zatem że będzie wynik. W praktyce nie powinieneś używaćget();
, aleorElse()
/orElseGet()
/orElseThrow()
(dla bardziej znaczącego błędu zamiast NSEE), ponieważ możesz nie wiedzieć, czy operacje zastosowane do potoku strumienia spowodują powstanie elementu..findFirst().orElse(null);
na przykładorElse
?Optional
typ, który.findFirst
powraca. Jednym z zastosowań Opcjonalnych jest pomoc deweloperom w unikaniu konieczności radzenia sobie znull
seg zamiast sprawdzaniamyObject != null
, możesz sprawdzaćmyOptional.isPresent()
lub używać innych części interfejsu opcjonalnego. Czy to wyjaśniło?Nie, nie zrobi tego - „pęknie”, gdy tylko zostanie znaleziony pierwszy element spełniający predykat. Możesz przeczytać więcej o lenistwie w pakiecie strumieniowym javadoc , w szczególności (wyróżnienie moje):
źródło
Musiałem odfiltrować tylko jeden obiekt z listy obiektów. Więc użyłem tego, mam nadzieję, że to pomoże.
źródło
.orElse(null) != null
. Zamiast tego skorzystaj z opcjonalnych interfejsów API,.isPresent
tj.findFirst().isPresent()
..stream().map(ParkingLot::getId).anyMatch(Predicate.isEqual(id))
Oprócz odpowiedzi Alexis C: Jeśli pracujesz z listą tablic, w której nie masz pewności, czy element, którego szukasz, istnieje, użyj tego.
Następnie można po prostu sprawdzić, czy jest .
null
źródło
źródło
Ulepszona odpowiedź One-Liner: jeśli szukasz logicznej wartości zwracanej, możemy to zrobić lepiej, dodając isPresent:
źródło