Документация из Stream.flatMap(Function<? extends T, ? extends Stream<? extends R>>)
:
Возвращает поток, состоящий из результатов замены каждого элемента этого потока содержимым сопоставленного потока, созданного с применением предоставленногофункция отображения на каждый элемент.Каждый сопоставленный поток закрывается после помещения его содержимого в этот поток.(Если сопоставленный поток равен null
, вместо него используется пустой поток.) Это промежуточная операция.
Примечание API:
Операция flatMap()
имеет эффект применения преобразования «один ко многим» к элементам потока, а затем сглаживания результирующих элементов в новый поток.
Как видите, метод используется дляДля каждого элемента создайте из них stream , затем сведите каждый поток в один поток (который возвращается методом).Таким образом:
List<Optional<Integer>> optionals = ...;
List<Integer> integers = optionals.stream()
.flatMap(optional -> optional) // identity function
.collect(Collectors.toList());
Не будет работать, поскольку функция возвращает Optional
, а не Stream
из Integer
с.Чтобы решить эту проблему, вам нужно изменить функцию, чтобы она возвращала Stream
того, что содержит Optional
.В зависимости от используемой версии Java вы можете:
Java 9 +,
List<Optional<Integer>> optionals = ...;
List<Integer> integers = optionals.stream()
.flatMap(Optional::stream)
.collect(Collectors.toList());
Java 8,
// There are different ways to convert an Optional into a Stream using
// flatMap, this is just one option. Holger shows other ways in the comments.
List<Optional<Integer>> optionals = ...;
List<Integer> integers = optionals.stream()
.flatMap(optional -> optional.isPresent() ? Stream.of(optional.get()) : Stream.empty())
.collect(Collectors.toList());
Другие параметрывключают использование map
в сочетании с filter
или методы Optional
.См. ответ Эрана для примеров.