| 維度 | Comparable (內部比較器) | Comparator (外部比較器) |
|---|---|---|
| 接口方法 | int compareTo(T o) | int compare(T o1, T o2) |
| 實現位置 | 實體類自身實現 implements Comparable<T> | 獨立類或 Lambda 實現 Comparator<T> |
| 排序調用 | Collections.sort(list) | Collections.sort(list, comparator) |
| 適用場景 | 自然順序、單一默認排序 | 多種排序策略、無法修改實體類、臨時排序 |
| 優先級 | 低(被 Comparator 覆蓋) | 高(顯式傳入時生效) |
import java.util.*;
class Cat implements Comparable<Cat>, Comparator<Cat> {
private String name;
private int age;
public Cat() {}
public Cat(String name, int age) { this.name = name; this.age = age; }
public String getName() { return name; }
public int getAge() { return age; }
// Comparable: 自然順序按年齡升序
@Override public int compareTo(Cat o) { return this.age - o.age; }
// Comparator: 外部比較器也按年齡升序(演示雙重實現)
@Override public int compare(Cat o1, Cat o2) { return o1.age - o2.age; }
@Override public String toString() { return "名字:" + name + ", 年齡:" + age; }
}
public class CollectionsSort {
public static void main(String[] args) {
List<Cat> list = Arrays.asList(
new Cat("a", 10), new Cat("b", 20), new Cat("c", 3)
);
// 方案 1: Comparable 自然順序
Collections.sort(list); // 年齡升序
System.out.println("升序:" + list);
Collections.sort(list, Collections.reverseOrder()); // 年齡降序
System.out.println("降序:" + list);
// 方案 2: Comparator 策略
Comparator<Cat> byAge = new Cat(); // 使用 Cat 自身的 compare()
Collections.sort(list, byAge);
System.out.println("Comparator 升序:" + list);
Collections.sort(list, Collections.reverseOrder(byAge));
System.out.println("Comparator 降序:" + list);
}
}
升序:[名字:c, 年齡:3, 名字:a, 年齡:10, 名字:b, 年齡:20]
降序:[名字:b, 年齡:20, 名字:a, 年齡:10, 名字:c, 年齡:3]
Comparator 升序:[名字:c, 年齡:3, 名字:a, 年齡:10, 名字:b, 年齡:20]
Comparator 降序:[名字:b, 年齡:20, 名字:a, 年齡:10, 名字:c, 年齡:3]
// 按名字字典序
public int compareTo(Cat o) { return this.name.compareTo(o.name); }
// Comparator 鏈式:先按年齡,年齡相同再按名字
Comparator<Cat> byAgeThenName = Comparator
.comparingInt(Cat::getAge)
.thenComparing(Cat::getName);
< 0:this < o(this 排前面)== 0:this == o> 0:this > o(this 排後面)Comparator.comparing... 鏈式 API,代碼可讀性極強。Comparator.nullsFirst() / nullsLast() 處理空值。Comparable 定義對象固有順序,Comparator 提供靈活外部策略。Java 8 後推薦以 Comparator.comparing() 鏈式構建比較器,配合 Stream sorted() 實現聲明式排序,徹底替代匿名內部類時代。