比较然后比较给出编译错误 [英] comparing and thenComparing gives compile error

查看:109
本文介绍了比较然后比较给出编译错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试按名称排序列出的员工,然后使用Java8 Comparator 年龄,我在下面创建了比较器但它给我一个编译器错误

I am trying to sort List of employees by name then age using Java8 Comparator, I have created below Comparator but it gives me a compiler error


类型不匹配:无法转换为Comparator< Object>至< unknown>



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

但如果我明确指定Type

but it works if I explicitly specify the Type

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

或创建两个 Compartor s和链

    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> ,但是为什么自动类型推断没有找到正确的类型并期望明确指定。

I have specified the type Comparator<String> on the left side but why auto type inference is not finding the correct Type and expecting to specify explicitly.

有人可以澄清这个吗?

这是代码

    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]


推荐答案

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

Java needs to know a type of all variables. In many lambdas it can infer a type, but in your first code snippet, it cannot guess the type of s. I think the standard way to solve that problem would be to declare it explicitly:

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

如果你看这个答案,它在 Comparator.comparing()的参数中有类似的类型声明。

If you look at this answer, it has a similar type declaration in the argument to Comparator.comparing().

你的方法,显式给出比较()的类型参数,显然也有效。

Your method, explicitly giving the type arguments of comparing(), obviously works too.

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

For your other method, declaring two comparators, I am pretty confident that in this case Java can infer from the String on the left side of the assignment, just as in the conventional List <String> = new ArrayList<>();. When you go on to call thenComparing() in the same expression, Java can no longer see that the type from the left side is relevant. It would be a bit like int size = new ArrayList<>().size(); This works too:

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

这篇关于比较然后比较给出编译错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆