Java 8 Example: Filter null values from a stream We can use lambda expression str -> str!= null inside stream filter() to filter out null values from a stream.
Get if Object is Not Null, else Throw Exception The method orElseThrow is more convient and safe method to use. It returns the object value if the object is not null. However, if the object is null it throws the specified exception. Note: the UserNotFoundException::new is an example of Constructor Reference.
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
You can do this in single 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, it's expensive call), you can do this:
requiredCars = cars.stream().filter(c -> {
String name = c.getName();
return name != null && name.startsWith("M");
});
Or in more sophisticated way:
requiredCars = cars.stream().filter(c ->
Optional.ofNullable(c.getName()).filter(name -> name.startsWith("M")).isPresent());
Leveraging the power of java.util.Optional#map()
:
List<Car> requiredCars = cars.stream()
.filter (car ->
Optional.ofNullable(car)
.map(Car::getName)
.map(name -> name.startsWith("M"))
.orElse(false) // what to do if either car or getName() yields null? false will filter out the element
)
.collect(Collectors.toList())
;
you can use this
List<Car> requiredCars = cars.stream()
.filter (t-> t!= null && StringUtils.startsWith(t.getName(),"M"))
.collect(Collectors.toList());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With