以下两个代码段会产生相同的结果。
使用flatMap
:
Stream.iterate(2, n -> n + 4)
.flatMap(n -> Stream.of(n, -(n + 2)));
map
后跟flatMap
使用identity
:
Stream.iterate(2, n -> n + 4)
.map(n -> Stream.of(n, -(n + 2)))
.flatMap(Function.identity());
因此,在flatten
接口中包含无参数Stream
方法(如Scala的Stream)似乎很自然,以允许将前一个示例写为:< / p>
Stream.iterate(2, n -> n + 4)
.map(n -> Stream.of(n, -(n + 2)))
.flatten();
那么为什么flatten()
API中没有Stream
方法?
答案 0 :(得分:6)
flatten
方法无法用Java实现。它只能在Stream<? extends Stream<?>>
上调用,但无法确定某些类型T extends Stream<R>
是否为R
。
如果你看一下Scala中的方法签名:
def flatten[B](implicit asTraversable: (A) ⇒ GenTraversableOnce[B]): Stream[B]
它实际上需要一个隐式证据参数,类型A
是某种类型B
的集合。
Java中的flatMap
方法采用函数T -> Stream<? extends R>
:
<R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
所以我们知道它可以展平为Stream<R>
。
flatten
的静态实现是可能的:
static <R> Stream<R> flatten(Stream<? extends Stream<? extends R>> stream) {
return stream.flatMap(Function.identity());
}