First, check if the Optional is present. If yes, then stream the list and filter the non-empty ones and print each of them.
optionalList.ifPresent(list -> list.stream()
.filter(Optional::isPresent)
.map(Optional::get)
.forEach(System.out::println));
Almost similar for the stream case too
optionalStream.ifPresent(stream -> stream
.filter(Optional::isPresent)
.map(Optional::get)
.forEach(System.out::println));
Answer from Thiyagu on Stack OverflowFirst, check if the Optional is present. If yes, then stream the list and filter the non-empty ones and print each of them.
optionalList.ifPresent(list -> list.stream()
.filter(Optional::isPresent)
.map(Optional::get)
.forEach(System.out::println));
Almost similar for the stream case too
optionalStream.ifPresent(stream -> stream
.filter(Optional::isPresent)
.map(Optional::get)
.forEach(System.out::println));
If you can use Java 9, it can be done like this:
optionalList.ifPresent(list -> list.stream()
.flatMap(Optional::stream)
.forEach(System.out::println));
For a stream of optionals it would be the same, without the first .stream() call.
With Java 8 you don't have the Optional::stream method available so you can do it yourself:
optionalList.ifPresent(list -> list.stream()
.flatMap(opt -> opt.map(Stream::of).orElseGet(Stream::empty))
.forEach(System.out::println));
And for a Stream of Optionals it would look like this:
optionalStream.ifPresent(stream -> stream
.flatMap(opt -> opt.map(Stream::of).orElseGet(Stream::empty))
.forEach(System.out::println));
Optional.stream()
java - How to convert an Optional<T> into a Stream<T>? - Stack Overflow
Why does Optional.of(List<String).stream() return a stream with a single element, the List<String> instead of a Stream of individual elements?
lambda - Iterate over an optional list of integers ifPresent - Stack Overflow
As pointed in the comments, the cleanest way to get a Stream is to use Optional.orElse method with Collections.emptyList:
Stream<Integer> stream = listOfNumbers.orElse(Collections.emptyList()).stream();
The other possible solution with Optional.map:
Stream<Integer> stream = listOfNumbers.map(List::stream).orElse(Stream.empty());
Update Java 9 :
Since jdk9, Optional has a new method stream(), which returns either a stream of one element, or an empty stream.
Thus, going from an Optional<List<Integer>> to an Stream<Integer> becomes
Stream<Integer> streamOfNumbers = listOfNumbers.stream().flatMap(List::stream);
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.
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.
You may do it this way:
return visits.stream()
.map(visit -> visit.orElse(null))
.filter(Objects::nonNull)
.collect(Collectors.toList());
Assuming visits is of type List<Optional<Visit>>.
Causes Of Your Code Not Compiling
Assuming that the variable visits is of type List<Optional<Visit>> the statement you posted:
Stream.of(visits).filter(value -> Optional.isPresent(value))
.map((Visit t) -> Optional.get(t))
.collect(Collectors.toList());
has the following problems:
Stream.of()takes either one element or many elements of typeTand creates a Stream. You usevisitsas one element of typeList<Optional<Visit>>and I think you intend to get a Stream ofOptional<Visit>which you may achieve by usingvisits.stream().filter(value -> Optional.isPresent(value))does invokeisPresent(T t)in a static way while the methodisPresent(T t)doesn't exist, neither statically nor as an instance method. I think what you intend to do is:filter(value -> value.isPresent())which is equal tofilter(Optional::isPresent). The difference of the second is thatOptional::isPresentdoes not invoke a static method but results in a method reference.map((Visit) t -> Optional.get(t))does as well invoke a methodget(T t)in a static way which doesn't exist, neither statically nor as an instance method. I think you intended to invokemap((Visit) t -> t.get())which is equal tomap(Optional::get).
Fixing those issues would result in the new statement:
visits.stream().filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
The difference to my solution is only that you map after filter. As a reader to get it right you need to remember that Optional::get will always return a non-null value. If you map first and filter second you do not have to remember there are no null values because you filter them out in the second step.
You could do it as follows:
List<Visit> visitsWithoutOptionals = visits.stream()
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());