java多级排序用comparator链式调用实现,优先级逐层比较:先comparing主字段,再thencomparing次字段,支持null处理、自定义逻辑及基本类型专用方法。

Java中用Arrays.sort实现多级排序,核心是构造一个能按优先级逐层比较的Comparator。链式调用Comparator.comparing配合thenComparing是最简洁、可读性最强的方式。
一级主排序 + 多级次排序
比如对Person对象先按年龄升序,年龄相同时按姓名字典序,姓名也相同时按ID降序:
Arrays.sort(people,
Comparator.comparing(Person::getAge)
.thenComparing(Person::getName)
.thenComparing(Person::getId, Comparator.reverseOrder())
);
每级比较只在前一级结果相等时触发,天然支持“稳定”的多级逻辑。
处理null值避免空指针
字段可能为null时,直接调用方法引用会抛NullPointerException。应使用Comparator.nullsFirst或nullsLast包装:
Comparator.comparing(Person::getCity, Comparator.nullsLast(String::compareTo))Comparator.comparing(Person::getScore, Comparator.nullsFirst(Comparator.naturalOrder()))
注意:nullsFirst/nullsLast必须作用于具体比较器(如String::compareTo),不能直接套在方法引用上。
自定义比较逻辑嵌入链中
当某级需复杂判断(如按城市拼音排序、按状态枚举顺序排),可用lambda或独立Comparator:
- 用lambda:
.thenComparing(p -> p.getCity().getPinyin()) - 用独立Comparator:
.thenComparing(Comparator.comparing(p -> p.getLevel().getPriority()))
只要返回类型可比较(实现Comparable或提供对应Comparator),就能无缝接入链式结构。
基本类型字段要小心装箱
对int、long等基本类型字段,别直接写Person::getAge——它返回int,而comparing泛型要求引用类型。正确写法:
-
Comparator.comparingInt(Person::getAge)(推荐,无装箱) -
Comparator.comparing(p -> (long) p.getTimestamp())或comparingLong
用comparingInt/comparingLong等专用方法,性能更好且语义更清晰。











