Java的flatMap在可选整数列表的列表中

Max*_*wer 8 java optional java-8 java-stream

我有以下一些简化的代码无法编译,我不明白为什么:

List<Optional<Integer>> list =
    new ArrayList<>();
List<Integer> flattened = 
  list
    .stream()
    .flatMap(i -> i)
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

编译器告诉我:

[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
Run Code Online (Sandbox Code Playgroud)

我承认我不习惯Java,但我必须参与一个项目.我在Scala中嘲笑了这一点,list.flatten并且list.flatMap(i => i)正如预期的那样等效工作:

val list = List(Some(1), Some(2), None)
list.flatten // List(1, 2)
Run Code Online (Sandbox Code Playgroud)

Java flatMap与众不同吗?

Era*_*ran 14

它应该是:

List<Integer> flattened = 
  list
    .stream()
    .filter (Optional::isPresent)
    .map(Optional::get)
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

flatMap期望一个将Stream元素转换为a的函数Stream.你应该使用map(提取的值Optional).此外,您需要过滤掉空Optionals(除非您希望将它们转换为nulls).

没有过滤:

List<Integer> flattened = 
  list
    .stream()
    .map(o -> o.orElse(null))
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)