在Comparator.comparing中,除String.CASE_INSENSITIVE_ORDER外还有哪些可用的keyComparator?
Comparator comparing(Function keyExtractor, Comparator keyComparator)
这个方法确实可以结合String.CASE_INSENSITIVE_ORDER实现不区分大小写的字符串排序,示例代码如下:
Comparator<Person> cmp = Comparator.comparing(Person::getLastName, String.CASE_INSENSITIVE_ORDER);
好问题!除了String.CASE_INSENSITIVE_ORDER,其实只要是实现了Comparator<T>接口的对象(且类型和key提取器返回的key类型匹配),都能作为第二个参数传入这个方法。下面给你几个常见的实用场景和对应的Comparator示例:
标准库提供的通用Comparator
Java的Comparator类自带了很多开箱即用的比较器,比如:- 倒序排序:用
Comparator.reverseOrder()可以实现与自然顺序相反的排序逻辑,比如对年龄倒序排列Person对象:// 按年龄从大到小排序Person Comparator<Person> ageDescComparator = Comparator.comparing(Person::getAge, Comparator.reverseOrder()); - 空值安全排序:如果提取的key可能为null,可以用
Comparator.nullsFirst()或Comparator.nullsLast()来处理,避免空指针异常:// 姓氏为null的Person排在最前面,非null的按自然顺序排序 Comparator<Person> nullSafeLastNameComparator = Comparator.comparing( Person::getLastName, Comparator.nullsFirst(Comparator.naturalOrder()) );
- 倒序排序:用
自定义逻辑的Comparator
你可以根据业务需求自己实现Comparator逻辑,比如按字符串长度排序Person的姓氏:// 按姓氏长度从小到大排序,长度相同则按自然顺序排列 Comparator<Person> lastNameLengthComparator = Comparator.comparing( Person::getLastName, (s1, s2) -> { int lengthCompare = Integer.compare(s1.length(), s2.length()); return lengthCompare != 0 ? lengthCompare : s1.compareTo(s2); } ); // 也可以用更简洁的链式写法 Comparator<Person> lastNameLengthComparator = Comparator.comparing( Person::getLastName, Comparator.comparingInt(String::length).thenComparing(Comparator.naturalOrder()) );日期/时间相关的Comparator
对于LocalDate、LocalDateTime这类日期时间类型,也可以定制排序逻辑,比如按生日的月份排序:// 按生日的月份排序,月份相同则按日期排序 Comparator<Person> birthMonthComparator = Comparator.comparing( Person::getBirthDate, Comparator.comparing(LocalDate::getMonth).thenComparing(LocalDate::getDayOfMonth) );
简单来说,任何符合泛型类型要求的Comparator实现(不管是标准库提供的还是自定义的),都可以作为keyComparator参数传入这个方法,完全可以根据你的具体排序需求灵活选择或实现。
内容的提问来源于stack exchange,提问作者Code Complete
相关产品推荐
相关产品推荐

