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

问题描述 投票:0回答:1

我正在尝试使用Java8按姓名和年龄对

List
员工进行排序
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

但如果我明确指定类型,它就会起作用

    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]
java java-8 comparator comparable
1个回答
12
投票

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()
的类型参数,显然也有效(
Comparator.<String, String>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]));
© www.soinside.com 2019 - 2024. All rights reserved.