java - 为什么在映射到 Callable<T> 时需要显式提供类型参数?

标签 java generics lambda type-inference java-8

当试图回答不同的问题时,我发现我的代码只有在我明确给出类型参数时才能编译(我知道,无论代码计算什么都没有意义):

public Double calculateResult(int value) {
    return 0.0d;
}

private void init2() {
    List<Callable<Double>> list = IntStream.range(1, 99)
            .<Callable<Double>>mapToObj(value -> (() -> calculateResult(value)))
            .collect(Collectors.toList());
}

删除类型参数时 <Callable<Double>>来自 mapToObj ,它不编译,并给出错误

cannot infer the type variable by itself

如果我将其更改为使用 Supplier<Double>,它也无法推断出参数或 DoubleSupplier .

为什么它不能推断类型参数?

更新,我正在用 Netbeans 8.0 编译它,还没有用 javac 编译器检查它。

最佳答案

这是我的理解。

问题是您希望编译器使用预期的赋值类型,在本例中为 List<Callable<Double>> , 来推断类型参数。然而,.mapToObj不是链中的最后一个语句,它不返回 List .

不过下面这段代码是有效的,因为在这里编译器可以匹配 .mapToObj 的结果。调用您已声明为返回类型的内容,因此它可以推断流的类型参数。

Stream<Callable<Double>> temporaryVariable = IntStream.range(1, 99)
    .mapToObj(value -> (() -> calculateResult(value)));
List<Callable<Double>> list = temporaryVariable.collect(Collectors.toList());

因为它不是链中的最后一条语句,如果我是编译器,我真的不会喜欢遍历 Stream<?> 的所有可能值。 (本质上是 .mapToObj 的返回类型)找到一个与下一个返回 List<Callable<Double>> 的调用相匹配的调用.

关于java - 为什么在映射到 Callable<T> 时需要显式提供类型参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22713863/

相关文章:

java - 如何检查 Java 中的某个项目是否在数组中?

java - 为什么 Class#getComponentType 返回 null 而不是 ArrayList (Java) 的泛型类型?

C# Generics - 根据对象类型找到正确的具体类

c# - 如何获取lambda表达式参数

Java URL 文本文件转字符串

java - 如何在 Maven 生成的 jar 中包含特定文件夹?

java - 为什么我无法在 Java 中将 Vector<Vector<Number>> 转换为 AbstractList<AbstractList<Number>>?

c++ - 在 boost::unordered_set 字符串中使用 Lambda 函数 - 不区分大小写

c# - 在不调用的情况下使用 MethodInvoker

java - 如何从 Velocity 模板访问对象的公共(public)字段