Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java lambda - how to traverse optional list/stream of optionals

Having an Optional List of Optional's like:

Optional<List<Optional<String>>> optionalList = Optional.of(
    Arrays.asList(
        Optional.empty(),
        Optional.of("ONE"),
        Optional.of("TWO")));

How to traverse optionalList to print out the string's ONE and TWO ?

What about having an Optional Stream of Optionals?

Optional<Stream<Optional<String>>> optionalStream = Optional.of(
    Stream.of(
        Optional.empty(),
        Optional.of("ONE"),
        Optional.of("TWO")));

Update: Thanks for answers, solution for optionalStream (non nested):

optionalStream
    .orElseGet(Stream::empty)
    .filter(Optional::isPresent)
    .map(Optional::get)
    .forEach(System.out::println);
like image 778
Sara Vino Avatar asked Aug 03 '18 08:08

Sara Vino


People also ask

How do you use optional streams?

Optional class in Java is used to get the sequential stream of the only value present in this Optional instance. If there is no value present in this Optional instance, then this method returns returns an empty Stream. Parameters: This method do not accept any parameter.

How do I return an optional List in Java?

Now let see an example of how to return a default value if Optional is empty i.e. doesn't contain a value. You can use the Optional. orElse() method to return the default value as shown in the following example: Person p = getPerson(); Address home = p.

How do I fetch an object from optional?

Retrieving the Value From Java 8 Optional Object Using get() Method. The get() method of Optional is simply used to return a value from the Optional object. Suppose the value is not present, then it throws the exception NoSuchElementException.


Video Answer


3 Answers

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));
like image 178
jbx Avatar answered Nov 15 '22 23:11

jbx


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));
like image 30
user7 Avatar answered Nov 15 '22 23:11

user7


You can indeed stream the Option<String> and filter only non empty values.

Optional<List<Optional<String>>> optionalList = Optional.of(Arrays.asList(Optional.empty(), Optional.of("ONE"), Optional.of("TWO")));

optionalList.orElseGet(ArrayList::new)
            .stream()
            .filter(Optional::isPresent)
            .map(Optional::get)           
            .forEach(System.out::println);

You can also use Optional.ifPresent() as suggested in another answers :

optionalList.ifPresent(l -> l.stream()
                             .filter(Optional::isPresent)
                             .map(Optional::get)                               
                             .forEach(System.out::println));

Personally I prefer the first way because it removes a nested level : I find it more pleasant to read.

like image 39
davidxxx Avatar answered Nov 16 '22 00:11

davidxxx