比较然后比较给出编译错误

时间:2016-11-09 04:43:28

标签: java java-8 comparator comparable

我正在尝试按名称对List员工进行排序,然后使用Java8 Comparator进行排序,我在Comparator下面创建但是它给了我一个编译错误

  

Type mismatch: cannot convert from Comparator<Object> to <unknown>

    Comparator<String> c = Comparator.comparing(s -> s.split("\\s+")[0])
            .thenComparingInt(s -> Integer.parseInt(s.split("\\s+")[1])); //compile error

但是如果我明确指定Type

,它就有效
    Comparator<String> c = Comparator.<String, String> comparing(s -> s.split("\\s+")[0])
            .thenComparingInt(s -> Integer.parseInt(s.split("\\s+")[1])); //works

或创建两个Compartor和链

    Comparator<String> name = Comparator.comparing(s -> s.split("\\s+")[0]);
    Comparator<String> age = Comparator.comparingInt(s -> Integer.parseInt(s.split("\\s+")[1]));
    Comparator<String> cc = name.thenComparing(age); //works

我在左侧指定了类型Comparator<String>但是为什么自动类型推断没有找到正确的类型并期望明确指定。

有人可以澄清这个吗?

这是代码

    String[] arr = { "alan 25", "mario 30", "alan 19", "mario 25" };
    Comparator<String> c = Comparator.<String, String> comparing(s -> s.split("\\s+")[0])
            .thenComparingInt(s -> Integer.parseInt(s.split("\\s+")[1]));
    List<String> sorted = Arrays.stream(arr).sorted(c).collect(Collectors.toList());
    System.out.println(sorted);

输出

[alan 19, alan 25, mario 25, mario 30]

1 个答案:

答案 0 :(得分:2)

Java需要知道所有变量的类型。在许多lambda中,它可以推断出一种类型,但是在你的第一个代码片段中,它无法猜出s的类型。我认为解决该问题的标准方法是明确声明:

    Comparator<String> c = Comparator.comparing((String s) -> s.split("\\s+")[0])
            .thenComparingInt(s -> Integer.parseInt(s.split("\\s+")[1]));

如果查看this answer,它在Comparator.comparing()的参数中有类似的类型声明。

明确给出comparing()类型参数的方法显然也有效。

对于你的另一种方法,声明两个比较器,我非常有信心,在这种情况下,Java可以从赋值左侧的String推断,就像在传统的List <String> = new ArrayList<>();中一样。当您继续在同一表达式中调用thenComparing()时,Java无法再看到左侧的类型是相关的。这有点像int size = new ArrayList<>().size();这也有效:

    Comparator<String> name = Comparator.comparing(s -> s.split("\\s+")[0]);
    Comparator<String> c = name.thenComparingInt(s -> Integer.parseInt(s.split("\\s+")[1]));