Max Power :
I have the following bit of simplified code that fails to compile and I don't understand why:
List<Optional<Integer>> list =
new ArrayList<>();
List<Integer> flattened =
list
.stream()
.flatMap(i -> i)
.collect(Collectors.toList());
The compiler tells me:
[ERROR] ... incompatible types: cannot infer type-variable(s) R
[ERROR] (argument mismatch; bad return type in lambda expression
[ERROR] Optional<Integer> cannot be converted to Stream<? extends R>)
[ERROR] where R,T are type-variables:
[ERROR] R extends Object declared in method <R>flatMap(Function<? super T,? extends Stream<? extends R>>)
[ERROR] T extends Object declared in interface Stream
I admit I'm not used to Java but I have to for a project. I mocked this in Scala where list.flatten
and the equivalent list.flatMap(i => i)
work just as expected:
val list = List(Some(1), Some(2), None)
list.flatten // List(1, 2)
Is Java's flatMap
different?
Eran :
It should be:
List<Integer> flattened =
list
.stream()
.filter (Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
Your flatMap
expects a function that transforms a Stream
element to a Stream
. You should use map
instead (to extract the value of the Optional
). In addition, you need to filter out empty Optional
s (unless you wish to transform them to null
s).
Without the filtering:
List<Integer> flattened =
list
.stream()
.map(o -> o.orElse(null))
.collect(Collectors.toList());