方法引用配合Comparator.comparing和thenComparing实现多级排序,一级用Person::getName,二级用thenComparing(Person::getAge)或thenComparingInt,三级可链式添加nullsLast、reverseOrder等,复杂逻辑可封装工具方法再引用。

方法引用在多级排序中配合 Comparator.comparing,核心是利用链式调用 thenComparing,每级都用方法引用替代 Lambda,让代码更简洁、可读性更强。
一级排序:用方法引用代替 Lambda
传统写法用 Lambda 获取字段值,比如按姓名排序:
list.sort((a, b) -> a.getName().compareTo(b.getName()));
改用 Comparator.comparing + 方法引用,更直观:
list.sort(Comparator.comparing(Person::getName));
这里 Person::getName 是方法引用,等价于 p -> p.getName(),但更短、更语义化。
立即学习“Java免费学习笔记(深入)”;
二级排序:用 thenComparing 链式叠加
当一级相同时按年龄升序,直接接 thenComparing:
list.sort(Comparator.comparing(Person::getName)
.thenComparing(Person::getAge));
注意:两个方法引用都无需参数,thenComparing 会自动复用前一个比较器的元素类型(这里是 Person),所以 Person::getAge 能直接用。
如果某字段是基本类型(如 int),推荐用 thenComparingInt 避免装箱:
.thenComparingInt(Person::getAge).thenComparingLong(Person::getId).thenComparingDouble(Person::getScore)
三级及以上:继续链式调用,支持逆序和空值处理
按姓名 → 年龄 → 分数降序,且允许 null 分数排最后:
list.sort(Comparator.comparing(Person::getName)
.thenComparing(Person::getAge)
.thenComparing(Person::getScore, Comparator.nullsLast(Comparator.reverseOrder())));
关键点:
- 每个
thenComparing都可传入自定义比较器,比如Comparator.reverseOrder()实现降序 -
Comparator.nullsLast或nullsFirst处理可能为 null 的字段,避免NullPointerException - 方法引用依然适用,只要目标方法签名匹配(无参、返回可比较类型)
复合字段或复杂逻辑?仍可用方法引用封装
如果排序依据不是简单 getter,而是组合逻辑(如“姓+名”全拼),可先写一个工具方法:
public static String getFullName(Person p) {
return p.getLastName() + p.getFirstName();
}
然后直接引用:
.thenComparing(PersonUtil::getFullName)
这样既保持方法引用的简洁性,又把业务逻辑收口到独立方法里,便于复用和测试。
不复杂但容易忽略:方法引用能用好的前提是目标方法是无参、返回值类型可自然排序(实现 Comparable)或已提供对应比较器。否则就得退回 Lambda 或自定义 Comparator。


















