I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE COURSE

1. Introduction

In this article, we’re going to talk about how to filter out non-empty values from a Stream of Optionals.

We’ll be looking at three different approaches – two using Java 8 and one using the new support in Java 9.

We will be working on the same list in all examples:

List<Optional<String>> listOfOptionals = Arrays.asList(
  Optional.empty(), Optional.of("foo"), Optional.empty(), Optional.of("bar"));

2. Using filter()

One of the options in Java 8 is to filter out the values with Optional::isPresent and then perform mapping with the Optional::get function to extract values:

List<String> filteredList = listOfOptionals.stream()
  .filter(Optional::isPresent)
  .map(Optional::get)
  .collect(Collectors.toList());

3. Using flatMap()

The other option would be to use flatMap with a lambda expression that converts an empty Optional to an empty Stream instance, and non-empty Optional to a Stream instance containing only one element:

List<String> filteredList = listOfOptionals.stream()
  .flatMap(o -> o.isPresent() ? Stream.of(o.get()) : Stream.empty())
  .collect(Collectors.toList());

Alternatively, you could apply the same approach using a different way of converting an Optional to Stream:

List<String> filteredList = listOfOptionals.stream()
  .flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty))
  .collect(Collectors.toList());

4. Java 9’s Optional::stream

All this will get quite simplified with the arrival of Java 9 that adds a stream() method to Optional.

This approach is similar to the one showed in section 3 but this time we are using a predefined method for converting Optional instance into a Stream instance:

It will return a stream of either one or zero element(s) whether the Optional value is or isn’t present:

List<String> filteredList = listOfOptionals.stream()
  .flatMap(Optional::stream)
  .collect(Collectors.toList());

5. Conclusion

With this, we’ve quickly seen three ways of filtering the present values out of a Stream of Optionals.

The full implementation of code samples can be found on the Github project.

I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE LESSONS

newest oldest most voted
Notify of
Xavier
Guest
Xavier

Why don’t you map your optional instead of checking if the value is present?
.flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty))

Grzegorz Piwowarek
Guest
Grzegorz Piwowarek

This is a very good suggesting indeed 🙂 Thanks! We will add it into our article. Cheers!