Comparable和Comparator
song

Comparable 和 Comparator 是 Java 中用于对象排序的两种接口,它们的主要区别在于使用场景和实现方式。

Comparable(自然排序) vs Comparator(自定义排序) 的区别

特性 Comparable Comparator
所在包 java.lang java.util
主要用途 默认的比较方式(对象自己知道如何比较) 自定义的比较方式(外部定义规则)
实现方式 自身实现 Comparable<T> 并重写 compareTo() 另创建一个类/匿名类实现 Comparator<T> 并重写 compare()
方法 int compareTo(T o) int compare(T o1, T o2)
影响的排序 自然排序(默认排序) 可以有多种排序方式
侵入性 需要修改原类 不需要修改原类
适用场景 适用于只有一种排序规则(如 String, Integer 适用于多个排序规则(如升序、降序、按多个字段排序)

如何选择?

  • 使用 Comparable

    • 当类有明确的自然排序规则时(如 String 按字典序排序)。
    • 当只需要一种排序规则时。
  • 使用 Comparator

    • 当需要多种排序规则时(如按姓名、年龄、工资等排序)。
    • 当无法修改类的源代码时(如对第三方库的类进行排序)。
    • 当需要临时定义排序规则时(如匿名内部类或 Lambda 表达式)。
  • **Comparable**:定义类的默认排序逻辑(自然顺序),简单但不够灵活。

  • **Comparator**:提供多种排序规则,灵活且解耦,是扩展排序能力的首选

Comparable

1
2
3
4
5
6
7
8
9
public class Person implements Comparable<Person> {
private String name;
private int age;

@Override
public int compareTo(Person o) {
return this.name.compareTo(o.name); // 按 name 排序
}
}

Comparator 详解

1
2
3
4
5
6
7
8
9
10
// 按 name 排序
Comparator<Person> nameComparator = (p1, p2) -> p1.getName().compareTo(p2.getName());

// 按 age 排序
Comparator<Person> ageComparator = (p1, p2) -> Integer.compare(p1.getAge(), p2.getAge());

// 使用 Comparator 排序
List<Person> people = new ArrayList<>();
people.sort(nameComparator); // 按 name 排序
people.sort(ageComparator); // 按 age 排序

联合使用

如果类已经实现了 Comparable,但仍需其他排序规则,可以用 Comparator 覆盖默认行为

1
2
3
4
5
6
7
8
9
10
11
12
List<Person> people = new ArrayList<>();

// 默认按 Comparable 的自然排序(姓名)
Collections.sort(people);

// 使用 Comparator 按年龄排序
Collections.sort(people, ageComparator);

// Java 8+ Stream 排序(按年龄倒序)
List<Person> sortedPeople = people.stream()
.sorted(Comparator.comparingInt(Person::getAge).reversed())
.toList();
由 Hexo 驱动 & 主题 Keep