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

选哪个取决于你有没有权限改类、需不需要多种排序方式、以及这个类本身有没有“默认该怎么排”的共识。
类本身能改,且只有一种自然顺序
比如学生按学号排、商品按ID排、日期按时间先后排——这种有明确业务含义的单一主序,就让类实现 Comparable。
- 在类里加
implements Comparable<YourClass> - 重写
compareTo(),用Integer.compare(a, b)或Objects.compare()避免溢出 - 之后直接
Collections.sort(list)就生效,不用额外传参数
类不能改,或要临时换规则
第三方库里的类(如 LocalDateTime)、别人写的 DTO、或者同一类需要按价格、按名称、按创建时间多种方式排序——这时用 Comparator。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 不碰原类,单独写一个比较器,可以是匿名内部类、Lambda 表达式或独立类
- 调用时显式传入:
Collections.sort(list, (a, b) -> a.getPrice().compareTo(b.getPrice())) - Java 8+ 推荐用 Lambda;复杂逻辑可抽成静态方法,比如
Person::compareByName
同一个类既要自然顺序,又要多套规则
常见于实体类:默认按 ID 升序(实现 Comparable),但查询时经常要按时间倒序、按状态分组再排序等。
立即学习“Java免费学习笔记(深入)”;
- 自然顺序走
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()方法比手动翻转更安全

















