为何需临时变量调用reversed()?如何实现Comparator单行排序?
这个报错的核心原因是Java编译器的类型推断限制:当你直接在Comparator.comparing(person -> person.age)后链式调用reversed()时,编译器无法从后续的方法调用中推断出lambda表达式person -> person.age的目标类型(即Function<Person, Integer>)——因为reversed()方法的返回类型是Comparator<T>,但此时前面的comparing方法的泛型参数还没被确定,导致类型推断失败。
下面是几种可以实现单行倒序排序的修正方案:
方案1:显式指定comparing方法的泛型类型
通过显式声明泛型参数<Person, Integer>,直接告诉编译器comparing方法接收的是从Person映射到Integer的函数,这样就能正确推断lambda的类型:
persons.sort(Comparator.<Person, Integer>comparing(person -> person.age).reversed());
方案2:使用comparingInt处理基本类型(推荐)
因为age是int基本类型,使用专门的comparingInt方法可以避免自动装箱,同时编译器能直接推断出lambda的参数类型为Person,完美解决类型推断问题:
persons.sort(Comparator.comparingInt(person -> person.age).reversed());
方案3:用方法引用替代lambda(如果有getter方法)
如果Person类为age字段提供了getAge() getter方法,使用方法引用可以让编译器更轻松地推断类型:
persons.sort(Comparator.comparing(Person::getAge).reversed());
为什么临时变量能正常工作?
当你把Comparator.comparing(person -> person.age)赋值给Comparator<Person>类型的变量时,编译器会根据变量的类型自动推断出comparing方法的泛型参数是Person和Integer,lambda的类型被明确后,后续调用reversed()自然不会报错。
完整的修正代码示例:
public class SubTypeComparatorIssue { public void sortAgeFromOldToYoung(List<Person> persons) { // 选择任意一种方案即可 persons.sort(Comparator.<Person, Integer>comparing(person -> person.age).reversed()); // persons.sort(Comparator.comparingInt(person -> person.age).reversed()); // persons.sort(Comparator.comparing(Person::getAge).reversed()); } } class Person { int age; // 方案3需要的getter方法 // public int getAge() { // return age; // } }
内容的提问来源于stack exchange,提问作者Thomas Mathew

