Filter values only if not null using lambda in Java8
In this particular example I think @Tagir is 100% correct get it into one filter and do the two checks. I wouldn't use Optional.ofNullable
the Optional stuff is really for return types not to be doing logic... but really neither here nor there.
I wanted to point out that java.util.Objects
has a nice method for this in a broad case, so you can do this:
cars.stream() .filter(Objects::nonNull)
Which will clear out your null objects. For anyone not familiar, that's the short-hand for the following:
cars.stream() .filter(car -> Objects.nonNull(car))
To partially answer the question at hand to return the list of car names that starts with "M"
:
cars.stream() .filter(car -> Objects.nonNull(car)) .map(car -> car.getName()) .filter(carName -> Objects.nonNull(carName)) .filter(carName -> carName.startsWith("M")) .collect(Collectors.toList());
Once you get used to the shorthand lambdas you could also do this:
cars.stream() .filter(Objects::nonNull) .map(Car::getName) // Assume the class name for car is Car .filter(Objects::nonNull) .filter(carName -> carName.startsWith("M")) .collect(Collectors.toList());
Unfortunately once you .map(Car::getName)
you'll only be returning the list of names, not the cars. So less beautiful but fully answers the question:
cars.stream() .filter(car -> Objects.nonNull(car)) .filter(car -> Objects.nonNull(car.getName())) .filter(car -> car.getName().startsWith("M")) .collect(Collectors.toList());
You just need to filter the cars that have a null
name:
requiredCars = cars.stream() .filter(c -> c.getName() != null) .filter(c -> c.getName().startsWith("M"));
The proposed answers are great. Just would like to suggest an improvement to handle the case of null list using Optional.ofNullable
, new feature in Java 8:
List<String> carsFiltered = Optional.ofNullable(cars) .orElseGet(Collections::emptyList) .stream() .filter(Objects::nonNull) .collect(Collectors.toList());
So, the full answer will be:
List<String> carsFiltered = Optional.ofNullable(cars) .orElseGet(Collections::emptyList) .stream() .filter(Objects::nonNull) //filtering car object that are null .map(Car::getName) //now it's a stream of Strings .filter(Objects::nonNull) //filtering null in Strings .filter(name -> name.startsWith("M")) .collect(Collectors.toList()); //back to List of Strings