java对象排序核心是arrays.sort()配合comparator,用声明式逻辑定义比较规则,底层采用稳定高效的timsort,需显式传入comparator避免按内存地址随机排序。

Java 对象排序的核心是 Arrays.sort() 配合 Comparator,不是写一堆 if-else,而是用声明式逻辑表达“怎么比”。它不改原数组结构,只重排引用顺序,底层用的是稳定、高效的 TimSort。
对象数组必须传 Comparator 才有意义
String[]、Person[] 这类引用类型数组,如果不传比较器,Arrays.sort() 默认按内存地址排序——结果完全随机,毫无业务价值。必须显式定义比较规则:
- 用 lambda 最简洁:
(a, b) -> a.getAge() - b.getAge()(升序),注意避免整数溢出,推荐用Integer.compare(a.getAge(), b.getAge()) - 用方法引用更清晰:
Comparator.comparing(Person::getName) - 降序直接链式调用:
Comparator.comparing(Person::getScore).reversed()
多字段排序靠 thenComparing 链式拼接
真实业务很少只看一个字段。比如先按部门分组,组内再按绩效排序,一行代码就能写完:
Arrays.sort(employees, Comparator.comparing(Employee::getDept).thenComparing(Employee::getPerformance))- 支持无限链:
.thenComparing(...).thenComparing(...) - 每个字段可独立指定升降序:
thenComparing(Employee::getSalary, Comparator.reverseOrder())
null 值必须主动兜底,否则直接崩
数组里有 null 是常见情况,但 Arrays.sort() 默认不处理,一碰到就抛 NullPointerException。不能依赖字段非空,得在比较器里提前防御:
- 让 null 排最后:
Comparator.nullsLast(Comparator.comparing(Person::getEmail)) - 让 null 排最前:
Comparator.nullsFirst(Comparator.naturalOrder()) - 字段本身可能为 null?别直接调
a.getName().compareTo(b.getName()),改用Comparator.comparing(Person::getName, Comparator.nullsLast(String::compareTo))
别为了降序把 int[] 转成 Integer[]
基本类型数组(如 int[])不接受 Comparator,强行装箱成 Integer[] 再排序,百万级数据会触发严重 GC 压力。真要降序,更优解是:
- 先
Arrays.sort(nums)升序,再用双指针原地翻转,零对象开销 - 或者用
Arrays.stream(nums).boxed().sorted(Collections.reverseOrder()).mapToInt(Integer::intValue).toArray()(仅限小数据,避免大数组)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











