两者都定义了对象的排序方式,但方式不同:Comparable 定义了一个类的自然排序(由该类自身实现),而 Comparator 定义了一个外部的、可选的排序(一个独立的对象)。选择取决于排序是内在的还是情景性的。
public class Person implements Comparable<Person> {
private String name;
private int age;
@Override
public int compareTo(Person other) { // defines THE natural order
return Integer.compare(this.age, other.age); // by age
}
// return: negative if this < other, 0 if equal, positive if this > other
}
List<Person> people = ...;
Collections.sort(people); // uses compareTo — sorts by age (the natural order)
Comparable 通过 compareTo() 存在于类内部,定义其唯一的默认排序。它被 Collections.sort、TreeSet、TreeMap 等自动使用。
// define orderings OUTSIDE the class — as many as you need
Comparator<Person> byName = (a, b) -> a.getName().compareTo(b.getName());
Comparator<Person> byAge = Comparator.comparingInt(Person::getAge);
people.sort(byName); // sort by name
people.sort(byAge.reversed()); // by age, descending
Comparator 是一个独立的对象,允许你为同一个类定义多个不同的排序,而无需修改该类。
Comparator<Person> comp = Comparator
.comparing(Person::getLastName) // primary: last name
.thenComparing(Person::getFirstName) // tie-break: first name
.thenComparingInt(Person::getAge) // then: age
.reversed(); // reverse the whole thing
people.sort(comp);
构建器风格的 comparing/thenComparing 方法使复杂的多字段排序简洁而易读。
Comparable → the class has ONE obvious natural order (numbers by value, strings
alphabetically, dates chronologically); you own the class
Comparator → you need MULTIPLE orderings, situational/custom ordering, OR you
can't modify the class (e.g. sorting a third-party type differently)
对象排序是持续的需求 — 排序列表、使用 TreeSet/TreeMap、查找最小值/最大值。
理解 Comparable-vs-Comparator 的区别让你做出正确的选择:Comparable 用于类的单一内在排序(内置、默认使用),Comparator 用于多个或外部排序的灵活性(按不同字段排序相同数据,或排序你无法控制的类型)。
现代流式 Comparator API(comparing/thenComparing/reversed)使多级排序优雅简洁。
掌握两者 — 以及何时各自适用 — 对于使用排序数据结构至关重要,也是 Java 中的常见实战和面试话题。