以下陈述虽然没有意义,但在句法上看起来很合理。
final Stream<LongStream> foobar = IntStream.empty()
.flatMap(x -> IntStream.empty()
.mapToObj(y -> IntStream.empty()
.mapToLong(z -> 1))); //compilation error here on `z -> 1`
然而它没有编译,返回:
java:不兼容的类型:lambda表达式中的错误返回类型 没有类型变量的实例U存在,以便java.util.stream.Stream符合java.util.stream.IntStream
但是如果延迟平面图,一切正常:
final Stream<LongStream> foobar = IntStream.empty()
.mapToObj(x -> IntStream.empty()
.mapToObj(y -> IntStream.empty()
.mapToLong(z -> 1)))
.flatMap(x -> x);
.mapToObj(..).flatMap(..)
和.flatMap(..)
之间有什么区别?有没有办法消除额外的flatmap调用?
答案 0 :(得分:6)
.mapToObj(..).flatMap(..)
和.flatMap(..)
期望完全不同的签名。
.mapToObj(..).flatMap(..)
需要int -> Object
函数和Object -> Stream<?>
函数。
.flatMap(..)
需要int -> IntStream
函数。
如果您分解代码,则会传递int -> Stream<LongStream>
函数,该函数与int -> IntStream
函数不兼容。
您将拥有same error这个简化代码:
IntStream.empty().flatMap(x -> Stream.of(LongStream.empty()));
答案 1 :(得分:1)
我已经重构了你的方法来分解他们正在做的事情:
IntFunction<LongStream> f1 = y -> IntStream.empty().mapToLong(z -> 1);
IntFunction<LongStream> f2 = x -> IntStream.empty().mapToObj(f1);
final Stream<LongStream> foobar = IntStream.empty().flatMap(f2);
我们在这里有两件事:
第2行的lambda不返回LongStream
,而是返回Stream<LongStream>
,因为我们正在将流中的每个int
转换为LongStream
。如果您打算将其作为单个LongStream
,则需要执行flatMapToLong
。
第3行的flatMap
需要一个int -> int
函数,而不是你的函数。但是,您可以使用mapToObj
代替,它采用您提供的方法。
所以纠正的方法是:
IntFunction<LongStream> f1 = y -> IntStream.empty().mapToLong(z -> 1);
IntFunction<LongStream> f2 = x -> IntStream.empty().mapToObj(f1).flatMapToLong(i -> i);
final Stream<LongStream> foobar = IntStream.empty().mapToObj(f2);