我正在尝试按名称对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]
答案 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]));