Java中对自定义对象列表排序需实现Comparable接口(自然排序)或传入Comparator(定制排序);前者适用于唯一公认逻辑,后者更灵活且支持Lambda与comparing链式调用;注意列表须可修改,JDK 8+推荐使用List.sort()替代Collections.sort()。

在 Java 中,Collections.sort() 可以对 List 进行排序,但要对自定义对象列表排序,必须明确告诉它“按什么规则排”——这通过实现 Comparable 接口(自然排序)或传入 Comparator(定制排序)来完成。
让类实现 Comparable 接口(自然排序)
适用于该类有唯一、公认的排序逻辑(比如学生按学号升序、商品按价格升序)。需重写 compareTo() 方法,返回负数、0 或正数表示小于、等于、大于。
- 在自定义类中实现
Comparable<yourclass></yourclass> -
compareTo()中用Integer.compare()、String.compareTo()等安全比较基本类型或字符串字段,避免空指针和整型溢出 - 若需多级排序(如先按年龄,年龄相同时按姓名),可链式判断
示例:
public class Person implements Comparableprivate String name;
private int age;
public int compareTo(Person o) {
int ageDiff = Integer.compare(this.age, o.age);
if (ageDiff != 0) return ageDiff;
return this.name.compareTo(o.name); // 年龄相同时按姓名字典序
}
}
使用 Comparator 匿名内部类或 Lambda 表达式(灵活定制)
更常用,适合同一类需多种排序方式(如按姓名升序、按年龄降序、按姓名长度排序),且不修改原类代码。
立即学习“Java免费学习笔记(深入)”;
- 调用
Collections.sort(list, comparator),传入Comparator实例 - JDK 8+ 推荐用 Lambda:简洁直观,如
(a, b) -> Integer.compare(a.getAge(), b.getAge()) - 也可用
Comparator.comparing()链式构造,支持 null 安全(comparing(..., nullsLast(String::compareTo)))和逆序(.reversed())
示例(按年龄降序):
Collections.sort(people, (p1, p2) -> Integer.compare(p2.getAge(), p1.getAge()));// 或更清晰写法:
Collections.sort(people, Comparator.comparingInt(Person::getAge).reversed());
注意 List 必须是可修改的(非不可变集合)
Collections.sort() 是就地排序,会直接修改原列表。如果传入的是 Arrays.asList() 返回的列表或 Collections.unmodifiableList() 包装的列表,运行时会抛 UnsupportedOperationException。
- 确保列表底层支持
set()操作(如ArrayList、LinkedList) - 若不确定,可先复制:
new ArrayList(originalList)
替代方案:使用 List.sort()(JDK 8+ 更推荐)
List 接口新增了 sort(Comparator) 默认方法,语义更清晰,且与流式 API 风格一致。
- 写法更简洁:
list.sort(Comparator.comparing(Person::getName)); - 功能完全等价于
Collections.sort(list, ...),只是调用主体不同 - 推荐新项目优先使用,语义更自然


















