Filter values ​​if not null using lambda in Java8

I have a list of objects: car . I want to filter this list based on some parameter using Java 8. But if the parameter is null , it throws a NullPointerException . How to filter null values?

The current code is as follows

 requiredCars = cars.stream().filter(c -> c.getName().startsWith("M")); 

This throws a NullPointerException if getName() returns null .

+134
java nullpointerexception null lambda java-8
01 Oct '15 at 9:36
source share
5 answers

In this specific example, I think @Tagir is 100% correct, put it in one filter and do two checks. I would not use Optional.ofNullable Optional - it really is that the return data types should not follow the logic ... but in fact, neither here nor there.

I would like to note that java.util.Objects has a good method for doing this in the broad case, so you can do this:

 cars.stream() .filter(Objects::nonNull) 

Which will clear your null objects. For those unfamiliar, this is a shorthand for the following:

 cars.stream() .filter(car -> Objects.nonNull(car)) 

To partially answer the question, we will return the list of car names that starts with the letter "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 shortened lambda, you can 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, as soon as you .map(Car::getName) you will only return a list of names, not 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()); 
+278
May 23 '16 at
source share
β€” -

You just need to filter out cars named null :

 requiredCars = cars.stream() .filter(c -> c.getName() != null) .filter(c -> c.getName().startsWith("M")); 
+46
Oct 01 '15 at 9:37
source share

The suggested answers are great. Just wanted to suggest an improvement for handling the null list case using Optional.ofNullable , a 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 would 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 a stream of Strings .filter(Objects::nonNull) //filtering null in Strings .filter(name -> name.startsWith("M")) .collect(Collectors.toList()); //back to List of Strings 
+38
Aug 29 '16 at 14:36
source share

You can do this with one filter step:

 requiredCars = cars.stream().filter(c -> c.getName() != null && c.getName().startsWith("M")); 

If you don't want to call getName() several times (for example, this is an expensive call), you can do this:

 requiredCars = cars.stream().filter(c -> { String name = c.getName(); return name != null && name.startsWith("M"); }); 

Or in a more complicated way:

 requiredCars = cars.stream().filter(c -> Optional.ofNullable(c.getName()).filter(name -> name.startsWith("M")).isPresent()); 
+20
Oct 01 '15 at 10:11
source share

You can use this

 List<Car> requiredCars = cars.stream() .filter (t-> t!= null && StringUtils.startsWith(t.getName(),"M")) .collect(Collectors.toList()); 
0
Jul 19 '19 at 1:37
source share



All Articles