java 8为comparator接口新增reversed()、thencomparing()等默认方法,支持链式组合、不可变设计与函数式编程;例如按年龄升序、分数降序、姓名字典序排序。

Java 8 为 Comparator 接口引入了多个实用的默认方法,大幅简化了比较逻辑的组合与复用。这些方法不强制实现类重写,直接可用,且支持链式调用,是函数式编程风格的重要体现。
核心新增默认方法一览
以下是 JDK 8 起在 Comparator<t></t> 中添加的关键默认方法(均返回新的 Comparator 实例,原接口保持不可变):
-
reversed():返回当前比较器的逆序版本(升序 ↔ 降序) -
thenComparing(Comparator super T> other):主比较结果相同时,按另一个比较器二次排序 -
thenComparing(Function super T, ? extends U> keyExtractor, Comparator super U> keyComparator):先提取关键属性,再用指定比较器比较该属性 -
thenComparing(Function super T, ? extends Comparable>> keyExtractor):提取可自然排序的属性(如String、Integer),自动按其自然序比较 -
thenComparingInt(ToIntFunction super T> keyExtractor)、thenComparingLong、thenComparingDouble:针对基本类型数值属性的高效比较(避免装箱)
典型链式组合用法
默认方法设计初衷就是支持“声明式”排序逻辑拼接。例如对 Student 类按年龄升序、同龄时按分数降序、分数也相同时按姓名字典序:
Comparator<student> cmp = Comparator.comparing(Student::getAge) // 主键:年龄升序
.thenComparing(Student::getScore, Comparator.reverseOrder()) // 次键:分数降序
.thenComparing(Student::getName); // 第三键:姓名升序</student>
这种写法清晰、无副作用,且每个方法都返回新对象,线程安全。
与静态工厂方法协同使用
默认方法常配合 Comparator 的静态方法使用,例如:
-
comparing()(静态)生成基础比较器,再用thenComparing(默认)追加规则 -
naturalOrder()/reverseOrder()(静态)提供通用序,可直接传入thenComparing(..., ...) -
nullsFirst()/nullsLast()(静态)处理空值,其返回值也是Comparator,可继续链式调用默认方法
示例(安全处理 null 姓名):
Comparator<student> safeByName = Comparator.comparing(
Student::getName,
Comparator.nullsLast(String.CASE_INSENSITIVE_ORDER)
).thenComparing(Student::getAge);</student>
注意点与常见误区
使用这些默认方法时需留意:
- 所有默认方法都不修改原比较器,每次调用产生新实例——适合函数式、不可变风格
- 链式调用中任一环节抛异常(如提取 null 属性未处理),整个排序会中断
-
thenComparing系列方法仅在前序比较结果为 0 时才触发,符合“稳定排序”的语义预期 - 若需重复使用复杂比较器,建议赋值给常量或方法,避免每次创建开销(虽小但可读性更佳)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











