Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8050820

Please add java.util.Optional.stream() to convert Optional<T> to Stream<T>

XMLWordPrintable

    • b50
    • generic
    • generic

        A DESCRIPTION OF THE REQUEST :
        Please add a method to java.util.Optional, similar to this:

              Stream<T> stream() {
                    return isPresent() ? Stream.of(get()) : Stream.empty();
              }

        or this:

              Stream<T> stream() {
                    return map(stream::of).orElseGet(Stream::empty());
              }

        or this:

              Stream<T> stream() {
                    return map(stream::of).orElse(Stream.empty());
              }

        depending on whichever is more efficient.

        JUSTIFICATION :
        Converting an Optional<T> to a Stream<T> containing 0 or one elements is often necessary when using features like Stream.flatMap(), which requires that the supplied function return a Stream<T>. However, the JDK provides no direct way to do this, and the user must resort to somewhat lengthy boilerplate code to work around this problem, which interferes with the readability of code.

        Getting a stream from a List or Set is easy and requires only a single method call to List.stream() or Set.stream(), but getting one from an Optional currently requires something like "optional.map(Stream::of).orElseGet(Stream::empty)" or "optional.isPresent() ? Stream.of(optional.get()) : Stream.empty()". This is inconvenient and makes often the code difficult to read, particularly if the surrounding code is also complex.

        Also, it is not immediately clear which of the proposed implementation alternatives shown above is most efficient, and if left to their own devices, users may not choose the best one, resulting in a (admittedly small) efficiency loss.

        Some user's experiences with this are described here:

        http://stackoverflow.com/questions/22725537/using-java-8s-optional-with-streamflatmap


        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        I would like to be able to do this:

              Optional<String> foo = Optional.of("Foo");
              Optional<String> emptyFoo = Optional.empty();

              Stream<String> fooStream = foo.stream(); // Contains only "Foo"
              assert emptyFoo.stream()==Stream.empty();

        In more complicated cases, the savings in readability over the workarounds can be substantial. Consider, for example:

            Optional<Integer> first = ...
            Optional<Integer> second = ...;
            Optional<Integer> third = ...;
            Optional<Integer> firstPresent = Stream.of(first.stream(), second.stream(), third.stream()).flatMap(s->s).findFirst();


        ACTUAL -
        There is no trivial way to get a Stream<T> from an Optional<T>.

        CUSTOMER SUBMITTED WORKAROUND :

        The user can write a static method in a utility class somewhere, like this:

        public static <T> Stream<T> optionalToStream(Optional<T> optional) {
        return optional.map(Stream::of).orElse(Stream.empty());
        }

        and then use it via static import. However, different users will write different such methods, with different names and different locations. This leads to code portability problems. Also, having to add an import and/or static import to use the method each time is a hassle.

              psandoz Paul Sandoz
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Created:
                Updated:
                Resolved: