皆為介面,用於自訂類別物件的大小比較,支援 Collections.sort()、Arrays.sort()、TreeSet、TreeMap 等排序容器。String、Integer 等內建類別已實作 Comparable,故可直接排序。
| 維度 | Comparable(內部比較) | Comparator(外部比較) |
|---|---|---|
| 定義位置 | 類別內部 implements Comparable<T> | 類別外部 獨立類別 implements Comparator<T> |
| 修改原始碼 | 需修改類別原始碼 | 無需修改原類別,適合第三方/不可變類別 |
| 比較邏輯 | 固定單一「自然順序」 | 可定義多種排序策略(依欄位、升降冪等) |
| 排序呼叫 | Collections.sort(list) | Collections.sort(list, comparator) |
| 方法簽名 | int compareTo(T o) | int compare(T o1, T o2) |
public class Person implements Comparable<Person> {
String name; int age;
@Override
public int compareTo(Person other) {
int cmp = this.name.compareTo(other.name);
return (cmp != 0) ? cmp : Integer.compare(this.age, other.age);
}
}
// 使用:Collections.sort(personList);
public class Person { String name; int age; } // 無需實作介面
public class PersonNameAgeComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
int cmp = p1.name.compareTo(p2.name);
return (cmp != 0) ? cmp : Integer.compare(p1.age, p2.age);
}
}
// 使用:Collections.sort(personList, new PersonNameAgeComparator());
// 依年齡降冪、名稱升冪
Comparator<Person> cmp = Comparator
.comparing(Person::getAge, Comparator.reverseOrder())
.thenComparing(Person::getName);
Collections.sort(list, cmp);
Comparable(簡單、直觀)。Comparator(彈性、解耦)。Comparable 定義預設順序,另提供 Comparator 供特殊場景使用。compareTo / compare 必須滿足傳遞性、反對稱性、一致性,否則排序行為未定義。return a - b 整數溢位,改用 Integer.compare(a, b)。Comparator 實作類別宜宣告為 static final 或單例,避免重複建立物件。