一个lambda表达式是否可以定义返回类型?

4

我有以下代码

Random rnd = new Random();
rnd.ints().limit(100)
          .filter(i-> i > 0)
          .map(Math::sqrt)
          .forEach(System.out::println)

这将会产生以下编译错误:

Streams.java:12: error: incompatible types: bad return type in method reference
                .map(Math::sqrt)
                     ^
    double cannot be converted to int

如果我使用以下内容
.mapToDouble(Math::sqrt)

它可以工作。问题在于编译器无法推断map中使用的lambda表达式的返回类型。有没有一种明确指定它的方法?我个人认为mapToxxx函数组有些笨拙。


1
可能与https://dev59.com/5GAf5IYBdhLWcg3wo0Bn有关。 - Oliver Charlesworth
1
哎呀,类型擦除又来了... - juanpa.arrivillaga
是的,你们两个都是对的,这正是我担心的事情。 - pablochacin
1
@juanpa.arrivillaga 不,这与擦除完全无关。这只是关于 OP 错误阅读文档的问题。 - Brian Goetz
@BrianGoetz 您是正确的。我太懒了!我以为 IntStreamStream 的子类,但实际上不是(它是 BaseStream 的子类),因此 map 方法的签名是不同的,正如您所指出的那样。 - pablochacin
1个回答

8
这与“声明lambda返回类型”无关。您只是向map()指定了一个无效的参数,因此编译器会告知您。
在IntStream中,map方法接受一个IntUnaryOperator(即从int到int的函数)。没有方法Math.sqrt可以转换为这个签名。

你是对的 @brian-goetz,我只是在想为什么需要 mapToxxx,如果 Stream 中的 map 函数已经定义为:<R> Stream<R> map(Function<? super T,? extends R> mapper) 并且被称为“返回一个由将给定函数应用于此流的元素的结果组成的流”。 - pablochacin
3
Stream 中的 map() 函数是这样定义的,因为 Stream 是对象引用的流。但是 IntStreamint 的流。如果我们像 Stream.map() 那样定义 Instream.map() ,结果将总是被装箱。这将使使用 IntStream 失去意义。 - Brian Goetz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接