比较然后比较给出编译错误
comparing and thenComparing gives compile error
我正在尝试使用 Java8 Comparator
按姓名然后按年龄对 List
员工进行排序,我在下面创建 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]
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]));
我正在尝试使用 Java8 Comparator
按姓名然后按年龄对 List
员工进行排序,我在下面创建 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]
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]));