Java 16

Stream.mapMulti has been added to JDK 16. This enables the following, without intermediate creation of single-element Streams:

Optional<Other> result =
    things.stream()
          .map(this::resolve)
          .<Other>mapMulti(Optional::ifPresent)
          .findFirst();

Java 9

Optional.stream has been added to JDK 9. This enables you to do the following, without the need of any helper method:

Optional<Other> result =
    things.stream()
          .map(this::resolve)
          .flatMap(Optional::stream)
          .findFirst();

Java 8

Yes, this was a small hole in the API, in that it's somewhat inconvenient to turn an Optional<T> into a zero-or-one length Stream<T>. You could do this:

Optional<Other> result =
    things.stream()
          .map(this::resolve)
          .flatMap(o -> o.isPresent() ? Stream.of(o.get()) : Stream.empty())
          .findFirst();

Having the ternary operator inside the flatMap is a bit cumbersome, though, so it might be better to write a little helper function to do this:

/**
 * Turns an Optional<T> into a Stream<T> of length zero or one depending upon
 * whether a value is present.
 */
static <T> Stream<T> streamopt(Optional<T> opt) {
    if (opt.isPresent())
        return Stream.of(opt.get());
    else
        return Stream.empty();
}

Optional<Other> result =
    things.stream()
          .flatMap(t -> streamopt(resolve(t)))
          .findFirst();

Here, I've inlined the call to resolve() instead of having a separate map() operation, but this is a matter of taste.

Answer from Stuart Marks on Stack Overflow
Top answer
1 of 13
371

Java 16

Stream.mapMulti has been added to JDK 16. This enables the following, without intermediate creation of single-element Streams:

Optional<Other> result =
    things.stream()
          .map(this::resolve)
          .<Other>mapMulti(Optional::ifPresent)
          .findFirst();

Java 9

Optional.stream has been added to JDK 9. This enables you to do the following, without the need of any helper method:

Optional<Other> result =
    things.stream()
          .map(this::resolve)
          .flatMap(Optional::stream)
          .findFirst();

Java 8

Yes, this was a small hole in the API, in that it's somewhat inconvenient to turn an Optional<T> into a zero-or-one length Stream<T>. You could do this:

Optional<Other> result =
    things.stream()
          .map(this::resolve)
          .flatMap(o -> o.isPresent() ? Stream.of(o.get()) : Stream.empty())
          .findFirst();

Having the ternary operator inside the flatMap is a bit cumbersome, though, so it might be better to write a little helper function to do this:

/**
 * Turns an Optional<T> into a Stream<T> of length zero or one depending upon
 * whether a value is present.
 */
static <T> Stream<T> streamopt(Optional<T> opt) {
    if (opt.isPresent())
        return Stream.of(opt.get());
    else
        return Stream.empty();
}

Optional<Other> result =
    things.stream()
          .flatMap(t -> streamopt(resolve(t)))
          .findFirst();

Here, I've inlined the call to resolve() instead of having a separate map() operation, but this is a matter of taste.

2 of 13
71

I'm adding this second answer based on a proposed edit by user srborlongan to my other answer. I think the technique proposed was interesting, but it wasn't really suitable as an edit to my answer. Others agreed and the proposed edit was voted down. (I wasn't one of the voters.) The technique has merit, though. It would have been best if srborlongan had posted his/her own answer. This hasn't happened yet, and I didn't want the technique to be lost in the mists of the StackOverflow rejected edit history, so I decided to surface it as a separate answer myself.

Basically the technique is to use some of the Optional methods in a clever way to avoid having to use a ternary operator (? :) or an if/else statement.

My inline example would be rewritten this way:

Optional<Other> result =
    things.stream()
          .map(this::resolve)
          .flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty))
          .findFirst();

An my example that uses a helper method would be rewritten this way:

/**
 * Turns an Optional<T> into a Stream<T> of length zero or one depending upon
 * whether a value is present.
 */
static <T> Stream<T> streamopt(Optional<T> opt) {
    return opt.map(Stream::of)
              .orElseGet(Stream::empty);
}

Optional<Other> result =
    things.stream()
          .flatMap(t -> streamopt(resolve(t)))
          .findFirst();

COMMENTARY

Let's compare the original vs modified versions directly:

// original
.flatMap(o -> o.isPresent() ? Stream.of(o.get()) : Stream.empty())

// modified
.flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty))

The original is a straightforward if workmanlike approach: we get an Optional<Other>; if it has a value, we return a stream containing that value, and if it has no value, we return an empty stream. Pretty simple and easy to explain.

The modification is clever and has the advantage that it avoids conditionals. (I know that some people dislike the ternary operator. If misused it can indeed make code hard to understand.) However, sometimes things can be too clever. The modified code also starts off with an Optional<Other>. Then it calls Optional.map which is defined as follows:

If a value is present, apply the provided mapping function to it, and if the result is non-null, return an Optional describing the result. Otherwise return an empty Optional.

The map(Stream::of) call returns an Optional<Stream<Other>>. If a value was present in the input Optional, the returned Optional contains a Stream that contains the single Other result. But if the value was not present, the result is an empty Optional.

Next, the call to orElseGet(Stream::empty) returns a value of type Stream<Other>. If its input value is present, it gets the value, which is the single-element Stream<Other>. Otherwise (if the input value is absent) it returns an empty Stream<Other>. So the result is correct, the same as the original conditional code.

In the comments discussing on my answer, regarding the rejected edit, I had described this technique as "more concise but also more obscure". I stand by this. It took me a while to figure out what it was doing, and it also took me a while to write up the above description of what it was doing. The key subtlety is the transformation from Optional<Other> to Optional<Stream<Other>>. Once you grok this it makes sense, but it wasn't obvious to me.

I'll acknowledge, though, that things that are initially obscure can become idiomatic over time. It might be that this technique ends up being the best way in practice, at least until Optional.stream gets added (if it ever does).

UPDATE: Optional.stream has been added to JDK 9.

🌐
Reddit
reddit.com › r/java › optional.stream()
r/java on Reddit: Optional.stream()
February 21, 2021 - It's wrapping in nullable Optional just to create a one element stream of it. Then goes on with creating a one element Stream containing a list just to break out of it right after.
Discussions

java - How to convert an Optional<T> into a Stream<T>? - Stack Overflow
I want to prepend a stream with an Optional. Since Stream.concat can only concatinate Streams I have this question: How do I convert an Optional into a Stream ? Example: Optional More on stackoverflow.com
🌐 stackoverflow.com
`Optional<Stream>.filter(Optional::isPresent).map(Optional::get)` to Java 11 `.flatMap(Optional::stream)`
What problem are you trying to solve? Java 8 Optional class didn't provide ::stream method. As a result of this unfortunate mistake a popular idiom was created to flatten a Stream of Optionals: .fi... More on github.com
🌐 github.com
2
October 6, 2023
Java Streams - how to convert Map <String, Optional<Object>> to Map <String, Object>?
still need help More on reddit.com
🌐 r/learnprogramming
4
1
August 26, 2022
Null safety
Optional is the go-to answer. And it's, effectively, wrong. I'll post the most workable answer within the confines of java in a separate comment because this will be quite long, but let's first delve into why Optional does not 'work' (will not 'solve' nullity in java) and why you probably shouldn't use it at all: Java introduced the stream ... More on reddit.com
🌐 r/java
229
100
August 13, 2024
🌐
Frankel
blog.frankel.ch › optional-stream
Optional.stream()
February 21, 2021 - public BigDecimal getOrderPrice(Long ... .reduce(BigDecimal.ZERO, BigDecimal::add); } The functional way is to wrap the orderId in an Optional....
🌐
Dev.java
dev.java › learn › api › streams › optionals
Using Optionals - Dev.java
Those methods are map(), filter(), and flatMap(). They take the same arguments as their twin methods from the Stream API, apart from flatMap(), that takes a function that returns an instance of Optional<T> instead of an instance of Stream.
🌐
TutorialsPoint
tutorialspoint.com › what-is-the-use-of-the-optional-stream-method-in-java-9
What is the use of the Optional.stream() method in Java 9?\\n
June 11, 2025 - This method helps to avoid explicit null checks by treating Optional as a container of zero or one element, which can be processed using stream operations. Below is an example of the Optional.stream() method in Java:
Find elsewhere
🌐
GeeksforGeeks
geeksforgeeks.org › java › optional-stream-method-in-java-with-examples
Optional stream() method in Java with examples - GeeksforGeeks
July 12, 2025 - Optional: Optional[9455] Getting the Stream: 9455 Program 2: ... // Java program to demonstrate // Optional.stream() method import java.util.*; public class GFG { public static void main(String[] args) { // create a Optional Optional<Integer> op = Optional.empty(); // print value System.out.println("Optional: " + op); try { // get the Stream System.out.println("Getting the Stream:"); op.stream().forEach(System.out::println); } catch (Exception e) { System.out.println(e); } } }
🌐
Medium
medium.com › @Sohjiro › working-with-streams-and-optionals-in-java-8-63dd26401fe6
Working with Streams and Optionals in Java 8 | by Felipe Juárez | Medium
October 2, 2017 - Instead, we can use the Optional class for removing that kind of conditions and just apply functions. Is in this moment were I remember what I told you at the begining: I had thought that the transition from Elixir to Java it would be painful, but Java 8 proved me that is not completely true
🌐
Medium
medium.com › @viraj_63415 › when-to-use-optional-stream-4ba745565f43
When to use Optional.stream(). Learn to integrate Java Optional into a… | by Viraj Shetty | Medium
February 6, 2024 - When to use Optional.stream() Learn to integrate Java Optional into a stream Pipeline Java Optional Optional class was introduced in JDK 8, as a means to reduce the occurrence of NullPointerException …
🌐
Javabeginnerstutorial
javabeginnerstutorial.com › code-base › how-to-use-optional-in-java-8-streams
How to use optional in java 8 streams - Java Beginners Tutorial
August 14, 2023 - First we will see how to filter null values using java 8 and Java 9 Optional. package com.jbt.core; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; /* * @author javabeginnerstutorial.com */ public class optional_java_8_stream { public static void main(String[] args) { List<jbt> list = new ArrayList<>(); list.add(new jbt("name1", 12)); list.add(new jbt("name2", null)); list.add(new jbt(null, 12)); String name = list.stream().map(jbt::getName) .filter(Optional::isPresent) .map(Optional::orElseThrow) .collect(Collectors.<em>joining</em>(",")); System.<em>out</em>.println(name); // Since JDK 9 name = list.stream() .map(jbt::getName) .flatMap(Optional::stream) .collect(Collectors.<em>joining</em>(",")); System.<em>out</em>.println(name); //orElse method can be used to provide default value incase there is no value present.
🌐
Oracle
docs.oracle.com › javase › 9 › docs › api › java › util › Optional.html
Optional (Java SE 9 & JDK 9 )
the result of applying an Optional-bearing mapping function to the value of this Optional, if a value is present, otherwise an empty Optional ... If a value is present, returns an Optional describing the value, otherwise returns an Optional produced by the supplying function.
🌐
Foojay
foojay.io › home › optional.stream()
Learning About Optional.stream() in OpenJDK and Java | foojay
August 23, 2021 - Fortunately, Optional offers a stream() method (since Java 9). It allows to simplify the functional pipeline:
🌐
Java Guides
javaguides.net › 2023 › 09 › java-optional-stream.html
Java Optional stream()
September 28, 2023 - The stream() method of the Optional class in Java is used to transform the Optional instance into a Stream.
🌐
Medium
medium.com › @dinukakasunmedis › exploring-java-optional-with-stream-api-2f091308113a
Exploring Java Optional with Stream API | by Dinuka Kasun Medis | Medium
October 8, 2024 - This is a container object that may or may not contain a value, offering a way to explicitly handle the absence of values rather than encountering null references. When combined with the Java Stream API, Optional becomes a highly useful tool ...
🌐
GitHub
github.com › openrewrite › rewrite-migrate-java › issues › 313
`Optional<Stream>.filter(Optional::isPresent).map(Optional::get)` to Java 11 `.flatMap(Optional::stream)` · Issue #313 · openrewrite/rewrite-migrate-java
October 6, 2023 - import java.util.Optional; import java.util.stream.Stream; class Scratch { public void foo() { Stream.of(Optional.empty()) .flatMap(Optional::stream); } } I already created the recipe as a way to familiarise with OpenRewrite.
Author   openrewrite
🌐
Java2s
java2s.com › Tutorials › Java › Java_Stream › 0035__Java_Optional.htm
Java Streams - Java Optional
The following code shows how to use the OptionalInt class: import java.util.OptionalInt; /*from w ww. jav a 2s.c o m*/ public class Main { public static void main(String[] args) { OptionalInt number = OptionalInt.of(2); if (number.isPresent()) { int value = number.getAsInt(); System.out.println("Number is " + value); } else { System.out.println("Number is absent."); } } } The code above generates the following result. Some stream operations return optional.
🌐
Baeldung
baeldung.com › home › java › java streams › filtering a stream of optionals in java
Filtering a Stream of Optionals in Java | Baeldung
January 8, 2024 - To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams: ... In this article, we’re going to talk about how to filter out non-empty values from a Stream of Optionals.
🌐
YouTube
youtube.com › watch
Java 8 Streams | Optional Usage and Best Practices | JavaTechie - YouTube
This tutorial will guide you java 8 Optional and its usecase with stream APIContent :What is Optional ?why Optional ?When to use Optional ?#javatechie #jav...
Published   January 22, 2021
🌐
Medium
medium.com › @satyendra.jaiswal › navigating-safely-a-comprehensive-guide-to-optional-and-null-handling-in-java-stream-api-c91afa20046e
Navigating Safely: A Comprehensive Guide to Optional and Null Handling in Java Stream API | by Satyendra Jaiswal | Medium
January 5, 2025 - Let’s start with the basics. Optional is a container object which may or may not contain a non-null value. It encourages developers to express the idea that a value might be absent rather than using null references.