编译时间:没有类型变量的实例U存在

时间:2017-03-15 05:42:42

标签: java java-8 java-stream

以下陈述虽然没有意义,但在句法上看起来很合理。

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调用?

2 个答案:

答案 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);