comparable是类自身实现的自然排序,需修改源码并定义compareto方法;comparator是外部定制的灵活比较策略,不修改原类即可支持多种排序逻辑。

核心区别在于:Comparable 是类自己声明“我会怎么比”,Comparator 是别人替你定义“现在要怎么比”。一个改类本身,一个不碰类代码。
Comparable 是类的自然排序能力
实现 Comparable 接口,等于给这个类打上“自带排序基因”的标签。它要求类内部定义 compareTo() 方法,告诉 JVM “我和同类对象比大小时,按什么规则来”。比如 String 按字典序、Integer 按数值大小,都是靠这个接口实现的。
关键点:
- 必须修改类源码,添加
implements Comparable<t></t>并实现compareTo - 只能有一套默认排序逻辑(例如只按年龄升序),无法临时切换
- 支持
Collections.sort(list)、Arrays.sort(arr),也能直接放进TreeSet或当TreeMap的 key - 方法签名是
int compareTo(T o),参数是“另一个同类型对象”
Comparator 是外部定制的比较策略
当你不能改原类(比如用的是第三方 jar 包里的类),或者同一类需要多种排序方式(比如一会儿按工资排,一会儿按姓名排),就用 Comparator。它是一个独立的比较器,和被比较的类完全解耦。
关键点:
- 不用动原有类,新建一个类/匿名类/Lambda 表达式实现
compare(T o1, T o2) - 可随时创建多个不同逻辑的比较器,灵活切换
- 调用时显式传入,如
Collections.sort(list, new SalaryComparator())或list.sort(Comparator.comparing(Employee::getName)) - 方法签名是
int compare(T o1, T o2),接收两个对象,返回比较结果
实际选哪个?看这三点
判断依据很直接:
- 如果这个类“天生就该有唯一公认的大小顺序”,比如日期、金额、编号——选 Comparable
- 如果排序规则多变、临时性强,或类你根本改不了——选 Comparator
- 如果想让类既支持默认排序,又保留扩展空间(比如后续加姓名排序)——两个都用:类实现 Comparable,再额外提供多个 Comparator
null 值和一致性提醒
这两个接口对 null 处理都不友好:compareTo(null) 或 compare(x, null) 默认抛 NullPointerException。如果业务允许 null,得在方法里手动判空。
另外,建议让 Comparable 的 compareTo 结果与 equals 保持一致。否则放进 TreeSet 时可能出现“逻辑相等但能同时存在”的异常行为。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











