为什么Stream API中没有flatten()方法?

Duš*_*šan 2 java-8 java-stream

以下两个代码段产生相同的结果.

flatMap:

Stream.iterate(2, n -> n + 4)
            .flatMap(n -> Stream.of(n, -(n + 2)));
Run Code Online (Sandbox Code Playgroud)

随着map其次是flatMap使用identity:

Stream.iterate(2, n -> n + 4)
            .map(n -> Stream.of(n, -(n + 2)))
            .flatMap(Function.identity());
Run Code Online (Sandbox Code Playgroud)

因此flatten,在Stream接口中包含无参数方法(如Scala的Stream)似乎很自然,允许将前面的示例写成:

Stream.iterate(2, n -> n + 4)
            .map(n -> Stream.of(n, -(n + 2)))
            .flatten();
Run Code Online (Sandbox Code Playgroud)

那么为什么API中没有flatten()方法Stream呢?

Bub*_*tan 6

一种flatten方法无法用Java实现.它只能在a上调用,Stream<? extends Stream<?>>但无法确定是否T extends Stream<R>为某种类型R.

如果您查看Scala中的方法签名:

def flatten[B](implicit asTraversable: (A) ? GenTraversableOnce[B]): Stream[B]
Run Code Online (Sandbox Code Playgroud)

它实际上需要一个隐式证据参数,该类型A是某种类型的集合B.

flatMapJava中的方法有一个函数T -> Stream<? extends R>:

<R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
Run Code Online (Sandbox Code Playgroud)

所以我们知道它可以被夷为平地Stream<R>.

静态实现flatten是可能的:

static <R> Stream<R> flatten(Stream<? extends Stream<? extends R>> stream) {
    return stream.flatMap(Function.identity());
}
Run Code Online (Sandbox Code Playgroud)