-2
 ArrayList<Optional<Test>> valueList= vv.values().stream().collect(Collectors.toList());
 

I'm getting the values into a list with the ArrayList<Optional<Test>> as the return type but I need to convert it to ArrayList<Test> without an optional return type.

How do I convert ArrayList<Optional<Test>> to ArrayList<Test> in Java 8 or Java 7?

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • Not your fault, but I consider that a poor design. They should have preferred to give you a `List` from the outset. I at least see no point in the `Optional` here. – Ole V.V. Jul 10 '20 at 16:34
  • What is your desired result? Do you want a shorter list with the non-present items removed, or do you want `null` in their place? – Ole V.V. Jul 10 '20 at 16:35
  • Does this answer your question? [Cast from Optional<> to ArrayList<>](https://stackoverflow.com/questions/31688382/cast-from-optional-to-arraylist) – Vikas Jul 11 '20 at 07:13

2 Answers2

3

1.Using filter()

One option in Java 8 is to filter out the values with Optional::isPresent and then perform mapping with the Optional::get function to extract values:

ArrayList<Test> testlist = valueList.stream()
  .filter(Optional::isPresent)
  .map(Optional::get)
  .collect(Collectors.toList());

2.Using flatMap()

Another option is use flatMap with a lambda expression that converts an empty Optional to an empty Stream instance, and non-empty Optional to a Stream instance containing only one element:

ArrayList<Test> testlist = valueList.stream()
  .flatMap(t -> t.isPresent() ? Stream.of(t.get()) : Stream.empty())
  .collect(Collectors.toList());

You can apply the same approach using method reference to converting an Optional to Stream:

ArrayList<Test> testlist = valueList.stream()
  .flatMap(t -> t.map(Stream::of).orElseGet(Stream::empty))
  .collect(Collectors.toList());

3.Java 9's Optional::stream

In Java 9, the stream() method has been added to the Optional class to improve its functionality.This is similar to the one showed in section 2, but this time we are using a predefined method for converting Optional instance into a Stream instance, If the Optional contains a value, then return a Stream containing the value. Otherwise, it returns an empty stream.

ArrayList<Test> testlist = valueList.stream()
  .flatMap(Optional::stream)
  .collect(Collectors.toList());
Dumidu Udayanga
  • 864
  • 2
  • 9
  • 21
2

Using Java 8 Streams you can do it like this:

    public static <T> List<T> unpackOptionals(List<Optional<T>> listOfOptionals) {
        return listOfOptionals.stream()
              .filter(Optional::isPresent)
              .map(Optional::get)
              .collect(Collectors.toList());
    }

Using Java 9 or above, you can use the method Optional.stream() to do the job:

    public static <T> List<T> unpackOptionals(List<Optional<T>> listOfOptionals) {
        return listOfOptionals.stream()
              .flatMap(Optional::stream)
              .collect(Collectors.toList());
    }

In Java 7 you shouldn't have any Optional (they were added in Java 8)

Felix
  • 2,256
  • 2
  • 15
  • 35