【问题标题】:Why do I need to explicitely give the type arguments when mapping to a Callable<T>?为什么在映射到 Callable<T> 时需要显式给出类型参数?
【发布时间】:2014-03-28 13:11:33
【问题描述】:

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

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());
}

当从mapToObj 中删除类型参数&lt;Callable&lt;Double&gt;&gt; 时,它不会编译,并给出它的错误

无法自行推断类型变量

如果我将其更改为使用Supplier&lt;Double&gt;DoubleSupplier,它也无法推断出参数。

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

更新,我是用Netbeans 8.0编译的,还没用javac编译器检查过。

【问题讨论】:

  • 不知道你用的是哪个版本的JDK 8。我得到了它的最新版本,我刚刚编译并运行了你的代码,没有任何问题。没有警告,没有编译器错误。一切顺利。
  • @EdwinDalorzo 您是否按照问题所述从mapToObj 中删除了&lt;Callable&lt;Double&gt;&gt;

标签: java generics lambda type-inference java-8


【解决方案1】:

这是我的理解。

问题在于您希望编译器使用预期的赋值类型(在本例中为 List&lt;Callable&lt;Double&gt;&gt;)来推断类型参数。但是,.mapToObj 不是链中的最后一个语句,它不会返回 List

下面的代码仍然有效,因为这里编译器可以将.mapToObj 调用的结果与您声明为返回类型的内容相匹配,因此它可以推断流的类型参数。

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

因为它不是链中的最后一条语句,如果我是编译器,我真的不想通过 Stream&lt;?&gt; 的所有可能值(本质上是 .mapToObj 的返回类型)来查找一个调用将匹配下一个调用以返回 List&lt;Callable&lt;Double&gt;&gt;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-30
    • 1970-01-01
    • 2021-02-20
    • 2019-10-14
    • 1970-01-01
    • 2014-11-22
    相关资源
    最近更新 更多