Java中实现自定义排序应优先使用Comparator接口,因其支持多维度、外部定义、null安全及链式组合;Comparable仅限单一自然排序。常用写法含匿名类、Lambda(推荐)和方法引用,Stream排序返回新列表,Collections.sort修改原列表。

在Java中实现自定义排序规则,核心是使用 Comparator 接口——它允许你脱离对象自身类的限制,灵活定义任意两个对象的大小关系。
为什么不用 Comparable?
Comparable 是“自然排序”,要求类本身实现该接口(比如 String、Integer),且只能有一种默认排序逻辑。而 Comparator 是“外部比较器”,一个类可以对应多个 Comparator,适用于同一类数据按不同维度排序(如按姓名、按年龄、按入职时间)。
三种常用写法对比
1. 匿名内部类(适合简单、一次性场景)
Collections.sort(employees, new Comparator() { @Override public int compare(Employee e1, Employee e2) { return e1.getAge() - e2.getAge(); // 升序 } });
2. Lambda 表达式(推荐,简洁清晰)
Collections.sort(employees, (e1, e2) -> e1.getSalary() - e2.getSalary());注意:基本类型差值可能溢出,建议用
Integer.compare(e1.getAge(), e2.getAge()) 替代减法
3. 方法引用 + 静态工具方法(复用性强)
// 定义在工具类中
public class EmployeeComparators {
public static Comparator byName() {
return Comparator.comparing(Employee::getName);
}
public static Comparator byAgeThenSalary() {
return Comparator.comparing(Employee::getAge)
.thenComparing(Employee::getSalary);
}
}
调用:employees.sort(EmployeeComparators.byAgeThenSalary());
立即学习“Java免费学习笔记(深入)”;
处理 null 和复杂逻辑的关键细节
• null 安全:直接调用 e1.getName().compareTo(...) 可能空指针。应使用:
– Comparator.nullsFirst(Comparator.comparing(Employee::getName))
– Comparator.nullsLast(...) 指定 null 排在最前或最后
• 多级排序:用 thenComparing() 链式组合,例如先按部门升序,部门相同时按薪资降序:
Comparator.comparing(Employee::getDept)
.thenComparing(Employee::getSalary, Comparator.reverseOrder())
• 逆序:不改原始逻辑,直接包装:Comparator.comparing(...).reversed() 或 Comparator.reverseOrder()
Stream 中的排序更直观
替代 Collections.sort,用 Stream API 更函数式:
Listsorted = employees.stream() .sorted(Comparator.comparing(Employee::getHireDate).reversed()) .collect(Collectors.toList());
注意:Stream 的 sorted() 返回新集合,不修改原列表;而 Collections.sort 修改原集合。










