应根据是否可修改类、是否需多种排序及是否存在默认排序共识来选择:可改类且有唯一自然顺序(如学生按学号)用comparable;不可改类或需多规则(如按价格、姓名)用comparator;二者可共存,前者定默认,后者供灵活定制。

选哪个取决于你有没有权限改类、需不需要多种排序方式、以及这个类本身有没有“默认该怎么排”的共识。
类本身能改,且只有一种自然顺序
比如学生按学号排、商品按ID排、日期按时间先后排——这种有明确业务含义的单一主序,就让类实现 Comparable。
- 在类里加
implements Comparable<yourclass></yourclass> - 重写
compareTo(),用Integer.compare(a, b)或Objects.compare()避免溢出 - 之后直接
Collections.sort(list)就生效,不用额外传参数
类不能改,或要临时换规则
第三方库里的类(如 LocalDateTime)、别人写的 DTO、或者同一类需要按价格、按名称、按创建时间多种方式排序——这时用 Comparator。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 不碰原类,单独写一个比较器,可以是匿名内部类、Lambda 表达式或独立类
- 调用时显式传入:
Collections.sort(list, (a, b) -> a.getPrice().compareTo(b.getPrice())) - Java 8+ 推荐用 Lambda;复杂逻辑可抽成静态方法,比如
Person::compareByName
同一个类既要自然顺序,又要多套规则
常见于实体类:默认按 ID 升序(实现 Comparable),但查询时经常要按时间倒序、按状态分组再排序等。
- 自然顺序走
Comparable,保证基础可用性 - 所有定制需求都用
Comparator实现,互不干扰 - 甚至可以组合:
Comparator.comparing(Person::getStatus).thenComparing(Person::getUpdateTime)
注意几个实际细节
别踩这些坑:
-
compareTo()和compare()返回负数/零/正数代表小于/等于/大于,别反了 - 如果集合含 null,
Comparable默认会抛NullPointerException,Comparator可用Comparator.nullsFirst()或nullsLast()处理 -
Collections.sort()只支持List,对Set或Map要先转成 List 再排 - 想降序?
Comparator.reverseOrder()或reversed()方法比手动翻转更安全
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










