1. 背景
在 Java 中,如果我们希望自定义类能够进行排序(例如在集合、数组中排序),就需要定义对象的比较规则。
Java 提供了两种方式:
Comparable<T>
接口 → 在类内部实现,定义对象的“自然顺序”。
Comparator<T>
接口 → 在类外部定义比较器,可以灵活指定不同的排序规则。
2.
Comparable
接口Java 中很多常用类都实现了
Comparable
接口,例如String
、Integer
。public class CompareToDemo { public static void main(String[] args) { // String 按字典序比较 System.out.println("apple".compareTo("banana")); // -1 System.out.println("dog".compareTo("dog")); // 0 System.out.println("zoo".compareTo("apple")); // 正数 // Integer 按数值大小比较 Integer a = 10, b = 20; System.out.println(a.compareTo(b)); // -1 System.out.println(b.compareTo(a)); // 1 System.out.println(a.compareTo(10));// 0 } }
2.1 定义
public interface Comparable<T> { int compareTo(T o); }
2.2 返回值含义
负数:当前对象 < 参数对象
0:当前对象 == 参数对象
正数:当前对象 > 参数对象
2.3 使用场景
当一个类本身就有固定的“自然排序规则”,可以直接实现
Comparable
。
3.
Comparator
接口3.1 定义
public interface Comparator<T> { int compare(T o1, T o2); }
3.2 返回值含义
与
Comparable
相同:
负数 → o1 < o2
0 → o1 == o2
正数 → o1 > o2
3.3 使用场景
当我们不想修改类本身,或者需要定义多种排序规则时,使用
Comparator
更灵活。
4.
Comparable
vsComparator
区别表
特性 Comparable
Comparator
方法 int compareTo(T o)
int compare(T o1, T o2)
定义位置 类 内部(实现接口) 类 外部(单独写比较器) 排序规则数量 一种(自然顺序) 多种(可定义多个 Comparator) 修改类代码需求 需要修改类本身 不需要修改类本身 常见使用场景 Collections.sort(list)
Collections.sort(list, comparator)
5. 示例:对
List<Student>
按age
排序5.1 使用
Comparable
class Student implements Comparable<Student> { private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } // 定义“自然顺序”:按年龄升序 @Override public int compareTo(Student other) { return Integer.compare(this.age, other.age); } @Override public String toString() { return name + "(" + age + ")"; } } public class ComparableDemo { public static void main(String[] args) { List<Student> list = new ArrayList<>(); list.add(new Student("Alice", 22)); list.add(new Student("Bob", 18)); list.add(new Student("Charlie", 20)); // 使用 Comparable 定义的 compareTo 方法排序 Collections.sort(list); System.out.println(list); // 输出: [Bob(18), Charlie(20), Alice(22)] } }
5.2 使用
Comparator
如果我们不想修改
Student
类,或者想要不同的排序规则,可以使用Comparator
。方式一:匿名内部类
Collections.sort(list, new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { return Integer.compare(s1.getAge(), s2.getAge()); } });
方式二:Lambda 表达式(Java 8+ 推荐)
list.sort((s1, s2) -> Integer.compare(s1.getAge(), s2.getAge()));
方式三:方法引用(更简洁)
list.sort(Comparator.comparing(Student::getAge));
👉 输出结果同样是:
[Bob(18), Charlie(20), Alice(22)]
6. 多条件排序(进阶)
6.1使用
Comparator
实现多条件排序使用
Comparator
时,可以轻松实现多条件排序。
例如:先按年龄升序,再按名字字母序升序//方式一、方法引用 + 链式 Comparator list.sort( Comparator.comparing(Student::getAge) .thenComparing(Student::getName) ); //方式二、匿名内部类写法 list.sort(new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { // 先按年龄排序 int result = Integer.compare(s1.getAge(), s2.getAge()); // 如果年龄相同,则按姓名排序 if (result == 0) { result = s1.getName().compareTo(s2.getName()); } return result; } }); //方式三、Lambda 表达式写法(Java 8+ 推荐) list.sort((s1, s2) -> { int result = Integer.compare(s1.getAge(), s2.getAge()); if (result == 0) { result = s1.getName().compareTo(s2.getName()); } return result; });
6.2 那是不是不能使用
Comparable完成多条件呢?
1️⃣
Comparable
的特点
Comparable
是 自然排序(对象自己规定的排序规则)。一个类 只能实现一次
compareTo
方法,也就是说只能有一种排序逻辑。例子:
public class Student implements Comparable<Student> { private int age; private String name; @Override public int compareTo(Student other) { // 先按年龄,再按姓名 int result = Integer.compare(this.age, other.age); if (result == 0) { result = this.name.compareTo(other.name); } return result; } }
👉 这样就能实现 多条件排序,但限制是 Student 这个类就被固定死了,始终用这一套排序规则。
2️⃣
Comparator
的特点
Comparator
是 外部比较器,不修改实体类本身。可以定义多个不同的排序规则,根据需要随时切换。
例子:
Comparator<Student> byAgeThenName = Comparator.comparing(Student::getAge) .thenComparing(Student::getName); Comparator<Student> byNameThenAge = Comparator.comparing(Student::getName) .thenComparing(Student::getAge);
👉 这样一个类(
Student
)就可以有 多种排序方式,灵活性更高。
3️⃣ 多条件的对比
Comparable:类内部定义,固定一种排序逻辑(可以写多条件,但只能有这一种)。
Comparator:类外部定义,可以有多种排序逻辑,灵活组合,推荐用于多条件排序。
👉 这样就能实现 多条件排序,但限制是 Student 这个类就被固定死了,始终用这一套排序规则。
✅ 多条件排序,
Comparable
也能实现(在compareTo
里写多条件逻辑)。
❌ 但是Comparable
只能有这一种排序方式,灵活性差。
👉 真正业务里,一般 多条件排序都会用Comparator
。
7. 总结
Comparable
:让类具备自然排序能力,适合“唯一固定规则”的场景。
Comparator
:外部比较器,适合需要定义多种排序规则的场景。对于
List<Student>
:
如果
Student
类实现了Comparable
,直接用Collections.sort(list)
。如果不想改
Student
类,可以用Comparator
方式排序。推荐使用
Comparator.comparing(...)
+ Lambda/方法引用,更简洁灵活。
java--Java 中的排序:Comparable 与 Comparator 的使用与区别
于 2025-08-31 11:11:48 首次发布