Mam do powiedzenia listę obiektów car
. Chcę przefiltrować tę listę na podstawie jakiegoś parametru przy użyciu języka Java 8. Ale jeśli parametr jest null
, wyrzuca NullPointerException
. Jak odfiltrować wartości null?
Obecny kod jest następujący
requiredCars = cars.stream().filter(c -> c.getName().startsWith("M"));
To rzuca się, NullPointerException
jeśli getName()
wróci null
.
Odpowiedzi:
W tym konkretnym przykładzie myślę, że @Tagir jest w 100% poprawny, włóż go do jednego filtra i wykonaj dwie kontrole. Nie użyłbym
Optional.ofNullable
opcjonalnych rzeczy, które są naprawdę dla typów zwracanych, aby nie wykonywać logiki ... ale tak naprawdę ani tu, ani tam.Chciałem zaznaczyć, że
java.util.Objects
ma na to fajną metodę w szerokim przypadku, więc możesz to zrobić:Który usunie twoje puste obiekty. Dla każdego, kto nie jest zaznajomiony, jest to krótka ręka na:
Aby częściowo odpowiedzieć na zadane pytanie, należy zwrócić listę nazw samochodów zaczynającą się od
"M"
:Gdy już przyzwyczaisz się do skróconych lambd, możesz również zrobić to:
Niestety, raz
.map(Car::getName)
zwrócisz tylko listę nazwisk, a nie samochody. Tak mniej piękna, ale w pełni odpowiada na pytanie:źródło
Objects::nonNull
nie można tego tutaj wykorzystać, a ostatnią radą powinno byćcars.stream() .filter(car -> Objects.nonNull(car.getName()))
wierzęcars.stream() .filter(car -> Objects.nonNull(car.getName()) && car.getName().startsWith("M"))
.startWith
może również spowodować zerowy wskaźnik. Chodziło mi o to, że Java dostarcza metodę specjalnie do filtrowania pustych obiektów ze strumieni.Objects.nonNull
jest to odpowiednik!= null
, twoja opcja jest krótszaString
) zamiast samochodów (Car
)?Wystarczy odfiltrować samochody, które mają
null
nazwę:źródło
Proponowane odpowiedzi są świetne. Wystarczy chciałby zaproponować lepszy obsłużyć przypadek liście zerowym użyciu
Optional.ofNullable
, nowej funkcji w Java 8 :Tak więc pełna odpowiedź będzie brzmiała:
źródło
Objects::nonNull
nie rozwiązuje problemu, ponieważ niezerowy samochód może mieć nazwę == nullMożesz to zrobić w jednym kroku filtrowania:
Jeśli nie chcesz dzwonić
getName()
kilka razy (na przykład jest to drogie połączenie), możesz to zrobić:Lub w bardziej wyrafinowany sposób:
źródło
Wykorzystanie mocy
java.util.Optional#map()
:źródło
możesz tego użyć
źródło