Java中对复杂对象多属性排序需用Comparator明确优先级,支持链式组合、升降序混搭和null安全处理;必须显式传入Comparator对象数组,基本类型数组不支持多条件排序。

Java 中用 Arrays.sort 对复杂对象做多属性排序,关键不是写一堆 if-else,而是用 Comparator 明确表达“先比什么、再比什么、怎么比”。它天然支持链式组合、升降序混搭和 null 安全处理,写对了既清晰又健壮。
多条件排序必须传 Comparator
对象数组(如 Student[])若未实现 Comparable,直接调用 Arrays.sort(arr) 会抛 ClassCastException。必须显式提供 Comparator——这是多属性排序的起点。
- 基本类型数组(
int[]、double[])不支持多条件,因为没有字段可取;如需按多维度排,得先转成包装类数组(Integer[]) - 字符串数组默认按字典序,但若要“先按长度、再按字典序”,仍需自定义
Comparator - 推荐用 Lambda 或
Comparator.comparing(),避免冗长的匿名内部类
链式拼接:按优先级一层层加规则
权重顺序即执行顺序:先满足的条件优先级最高,相等时才触发下一级。用 comparing() 起头,thenComparing() 追加,支持无限嵌套。
- 先按姓名升序,再按年龄降序:
Comparator.comparing(Student::getName).thenComparing(Student::getAge, Comparator.reverseOrder()) - 先按分数降序,再按年龄升序,最后按姓名字典序:
Comparator.comparing((Student s) -> s.score).reversed().thenComparing(s -> s.age).thenComparing(s -> s.name) - 支持方法引用、Lambda、甚至嵌套取值,比如
comparing(p -> p.getAddress().getCity()),但要注意空指针风险
null 值必须主动防御
Arrays.sort 默认不处理 null,遇到就会抛 NullPointerException。不能靠运气,得在比较器里明确策略。
立即学习“Java免费学习笔记(深入)”;
- 对可能为 null 的字符串字段:
Comparator.comparing(Student::getName, Comparator.nullsLast(String::compareTo)) - 对数值字段(如
Integer age),用comparingInt前确保非 null;若字段本身是原始类型(int age),则不会为 null,无需额外处理 - 避免对 null 对象调用
getXXX(),可在 lambda 中先判空,或统一用Objects.toString()等兜底
稳定性和兜底去重
对象数组排序使用的是稳定排序(Timsort 变种),相同元素相对位置不变。但若多个字段完全相等,有时需要强制打破并列,比如按原始索引或唯一 ID 排。
- 两个学生姓名、年龄、分数全等?排序后仍保持原先后顺序(稳定)
- 想让结果可预测且唯一,可在最后加兜底:
.thenComparingInt(Student::getId) - 注意:基本类型数组(如
int[])用的是双轴快排,不保证稳定;稳定性只针对对象数组有效


















