比较然后比较会得到编译错误

2022-09-03 02:42:48

我正在尝试使用Java8按姓名排序员工,然后使用年龄,我已经在下面创建了,但它给了我一个编译器错误ListComparatorComparator

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

但是如果我显式指定类型,它的工作原理

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

或通过创建两个 s 和链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

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

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

如果您查看此答案,它在参数中具有与 类似的类型声明。Comparator.comparing()

您的方法显式给出 的类型参数 ,显然也有效。comparing()

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

答案 2

推荐