Filtering a Stream of Optionals in Java

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.

Related posts:

Java Program to Implement Binomial Tree
Java Program to Implement the Program Used in grep/egrep/fgrep
Java Program to Implement WeakHashMap API
Java Program to Implement Bit Array
A Guide to WatchService in Java NIO2
Simplify the DAO with Spring and Java Generics
Adding Parameters to HttpClient Requests
New in Spring Security OAuth2 – Verify Claims
Count Occurrences of a Char in a String
Hướng dẫn Java Design Pattern – MVC
Tìm hiểu về Web Service
Java Program to Check if a Given Binary Tree is an AVL Tree or Not
Tips for dealing with HTTP-related problems
Inheritance and Composition (Is-a vs Has-a relationship) in Java
Hướng dẫn Java Design Pattern – Intercepting Filter
Java Program to Perform Encoding of a Message Using Matrix Multiplication
Java Program to Implement JobStateReasons API
Java Program to Implement TreeMap API
Guide to BufferedReader
Feign – Tạo ứng dụng Java RESTful Client
Java Program to Find a Good Feedback Edge Set in a Graph
Java Program to Implement Hash Tables with Double Hashing
Java Program to Implement Pagoda
Spring Cloud – Tracing Services with Zipkin
Java Program to Implement Pollard Rho Algorithm
Java Program to Implement the MD5 Algorithm
Transaction Propagation and Isolation in Spring @Transactional
Java Program to Repeatedly Search the Same Text (such as Bible by building a Data Structure)
Hướng dẫn sử dụng lớp Console trong java
Java Program to Implement LinkedHashSet API
Java Program to Check Cycle in a Graph using Topological Sort
Returning Custom Status Codes from Spring Controllers