76

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<T> into a Stream<T>?

Example:

Optional<String> optional = Optional.of("Hello");
Stream<String> texts = optional.stream(); // not working
slartidan
  • 18,794
  • 12
  • 78
  • 122
  • 1
    See http://stackoverflow.com/questions/22725537/using-java-8s-optional-with-streamflatmap – Alexis C. Nov 26 '15 at 15:54
  • That question indeed answers this one, but it presents a more complex example. I think this one is worth keeping for the simple case. – Didier L Nov 27 '15 at 10:48

7 Answers7

147

If restricted with Java-8, you can do this:

Stream<String> texts = optional.map(Stream::of).orElseGet(Stream::empty);
Naman
  • 21,685
  • 24
  • 196
  • 332
slartidan
  • 18,794
  • 12
  • 78
  • 122
  • 4
    I upvoted this because Java 9 has some non-backward compatible changes for some projects in their current state. Some projects, such as [lombok](https://github.com/rzwitserloot/lombok/issues/985), are part of core corporate artifacts that are slow to be changed. – Paul FREAKN Baker Oct 05 '17 at 20:05
  • If by any chance your optional happens to contain a `List` instead of a single `String` object, you just need to replace `Stream::of` with `List::stream`. The same applies to any other type of collection. You can also just use `Collection::stream`. Else you will get a `Stream>` which is probably _not_ what you wanted. – walen Oct 04 '19 at 11:55
  • @walen the question is to convert an `Optional` to `Stream` if the T is `List`, so be it. The answer stands correct still. What you might be looking for is flattening the collection. Aside, you are already on the wrong path if you have ended up using `Optional>`. – Naman Nov 13 '20 at 14:34
  • @Naman No need to justify the answer — I didn't say it wasn't correct. I just gave a tip on how to apply this solution to an `Optional` containing a `List`, which is a scenario some people might encounter. – walen Nov 14 '20 at 15:56
82

In Java-9 the missing stream() method is added, so this code works:

Stream<String> texts = optional.stream();

See JDK-8050820. Download Java-9 here.

slartidan
  • 18,794
  • 12
  • 78
  • 122
Tagir Valeev
  • 92,683
  • 18
  • 210
  • 320
8

You can do:

Stream<String> texts = optional.isPresent() ? Stream.of(optional.get()) : Stream.empty();
Konstantin Yovkov
  • 60,548
  • 8
  • 97
  • 143
  • 14
    I'm not a big fan of `isPresent`, it feels like a legacy method to me and reminds me of the times before Java8. But thanks for providing an alternative solution. – slartidan Nov 26 '15 at 15:56
  • Less fluent than the `map().orElseGet()` approach but probably slightly more efficient. – augurar Jul 23 '18 at 01:53
8

I can recommend Guava's Streams.stream(optional) method if you are not on Java 9. A simple example:

Streams.stream(Optional.of("Hello"))

Also possible to static import Streams.stream, so you can just write

stream(Optional.of("Hello"))
Utku Özdemir
  • 6,980
  • 2
  • 47
  • 48
1

If you're on an older version of Java (lookin' at you, Android) and are using the aNNiMON Lightweight Stream API, you can do something along the lines of the following:

    final List<String> flintstones = new ArrayList<String>(){{
        add("Fred");
        add("Wilma");
        add("Pebbles");
    }};

    final List<String> another = Optional.ofNullable(flintstones)
            .map(Stream::of)
            .orElseGet(Stream::empty)
            .toList();

This example just makes a copy of the list.

JohnnyLambada
  • 12,220
  • 11
  • 55
  • 59
0

A nice library from one of my ex collegues is Streamify. A lot of collectors, creating streams from practicly everything.

https://github.com/sourcy/streamify

Creating a stream form an optional in streamify:

Streamify.stream(optional)
Gábor Lipták
  • 9,470
  • 2
  • 57
  • 110
0

It can depend of how you want to convert empty optional to stream element. If you want to interpret it as "nothing" (or "no element"):

Stream<String> texts = optional.stream(); // since JDK 9
Stream<String> texts = optional.map(Stream::of).orElseGet(Stream::empty); // JDK 8

But if you want to interpret it as null:

Stream<String> texts = Stream.of(optional.oreElse(null));
JustAnotherCoder
  • 591
  • 6
  • 13