混合泛型方法和Java 8语法的复合表达式无法编译

时间:2014-10-14 06:50:36

标签: java generics java-8

使用Java 8更新20,下面的类不编译,它失败并出现“不兼容的类型:无法推断类型变量”的错误。但是,使用Eclipse 4.4.0,它可以使用JDT编译器进行编译和运行。要使用标准Java编译器进行编译,必须单独执行转换letters.stream().map(l -> l + "1").collect(Collectors.toList())。有谁知道这是Java编译器中的错误还是规范的一部分?如果这种行为符合预期,为什么JDT和标准编译器会有所不同?

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class CompileTest {

    public static void main(String[] args) {
        List<String> letters = Arrays.asList("A", "B", "C", "D", "E");
        int pos = Collections.binarySearch(letters.stream().map(l -> l + "1").collect(Collectors.toList()), "C1", (l1, l2) -> l1.compareTo(l2));
        System.out.println(pos);
    }

}

1 个答案:

答案 0 :(得分:1)

您遇到了当前jdk1.8.0_20中的错误。使用jdk1.8.0_40的beta版,它可以正确编译。

您可以使用jdk1.8.0_20

的变通方法
List<String> letters = Arrays.asList("A", "B", "C", "D", "E");
int pos = Collections.<String>binarySearch(
    letters.stream().map(l -> l + "1").collect(Collectors.toList()),
    "C1", (l1, l2) -> l1.compareTo(l2));
System.out.println(pos);

或者用方法引用替换Comparator的lambda表达式。这给了编译器一个关于compareTo将被调用的类型的提示:

List<String> letters = Arrays.asList("A", "B", "C", "D", "E");
int pos = Collections.binarySearch(
    letters.stream().map(l -> l + "1").collect(Collectors.toList()),
    "C1", String::compareTo);
System.out.println(pos);

但您也可以简化代码。由于String已经实现了Comparable,因此您无需为Comparator指定lambda表达式:

List<String> letters = Arrays.asList("A", "B", "C", "D", "E");
int pos = Collections.binarySearch(
    letters.stream().map(l -> l + "1").collect(Collectors.toList()), "C1");
System.out.println(pos);

这种简化具有降低类型推断复杂性的副作用,可以使用jdk1.8.0_20进行编译而不会出现问题。