java中arrays.sort对复杂对象排序需实现comparable接口定义自然顺序,或传入comparator指定临时规则;支持lambda、链式比较及null处理,但基本类型数组不支持comparator。

Java中用Arrays.sort对复杂对象排序,核心在于明确告诉它“按什么规则排”——要么让对象自己实现Comparable接口定义自然顺序,要么外部传入Comparator指定临时规则。
让对象自己知道怎么比:实现Comparable
如果某个类的“主要排序方式”是固定的(比如Student默认按学号升序),就让它实现Comparable接口,重写compareTo方法:
public class Student implements Comparable<student> {
private int id;
private String name;
private double score;
<pre class="brush:java;toolbar:false;">@Override
public int compareTo(Student other) {
return Integer.compare(this.id, other.id); // 按id升序
}
} // 使用时直接sort,无需额外参数 Student[] students = { / ... / }; Arrays.sort(students); // 自动按id排序
注意:compareTo返回负数表示当前对象小,0表示相等,正数表示当前对象大;推荐用Integer.compare、Double.compare等工具方法,避免手动减法导致溢出。
临时换种方式排:用Comparator匿名或Lambda
同一类对象常需多种排序逻辑(比如按姓名、按分数、按姓名+分数组合)。这时不改类定义,而是调用Arrays.sort时传Comparator:
- 按姓名升序:
Arrays.sort(students, (a, b) -> a.getName().compareTo(b.getName())) - 按分数降序:
Arrays.sort(students, (a, b) -> Double.compare(b.getScore(), a.getScore())) - 先按姓名再按分数(复合排序):
Arrays.sort(students, Comparator.comparing(Student::getName).thenComparing(Student::getScore))
Java 8+ 的Comparator链式写法清晰易读,comparing和thenComparing可嵌套多级,null值处理可用comparing(…, nullsLast(String::compareTo))。
数组元素为null?提前检查或定制比较器
Arrays.sort本身不支持null元素(会抛NullPointerException)。常见应对方式:
- 排序前过滤掉null:
students = Arrays.stream(students).filter(Objects::nonNull).toArray(Student[]::new); - 在Comparator里主动处理:
Comparator.nullsLast(Comparator.comparing(Student::getName)),把null排在最后 - 自定义Comparator判断null:
(a, b) -> { if (a == null && b == null) return 0; if (a == null) return 1; if (b == null) return -1; return a.getName().compareTo(b.getName()); }
原始类型数组 vs 对象数组:别用错方法
容易混淆的一点:Arrays.sort(int[])和Arrays.sort(Integer[])底层不同。前者用双轴快排(优化版),后者走对象排序流程(Timsort)。若误将int[]当作Integer[]传给需要Comparator的重载方法,编译直接报错。记住:
- 基本类型数组(
int[]、double[]等):只能用无参sort,不支持自定义比较器 - 包装类数组(
Integer[]、Double[]等):可用Comparator,但注意自动装箱/拆箱开销
需要按规则排基本类型?先转成包装类数组,或改用Stream(如IntStream.of(arr).sorted().toArray())。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











