首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 比較器大比拚:Comparable vs Comparator 核心差異與實戰選型

     編輯:Java 綜合教學

共同點

皆為介面,用於自訂類別物件的大小比較,支援 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)

程式碼範例

1. Comparable 實作

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);

2. Comparator 實作

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());

3. Java 8+ Lambda 與靜態工廠簡化


// 依年齡降冪、名稱升冪
Comparator<Person> cmp = Comparator
    .comparing(Person::getAge, Comparator.reverseOrder())
    .thenComparing(Person::getName);
Collections.sort(list, cmp);

選型指南

  • 單一自然順序、可改原始碼 → Comparable(簡單、直觀)。
  • 多種排序需求、不可改原始碼、策略模式 → Comparator(彈性、解耦)。
  • 兩者可共存:類別實作 Comparable 定義預設順序,另提供 Comparator 供特殊場景使用。

常見陷阱

  1. compareTo / compare 必須滿足傳遞性、反對稱性、一致性,否則排序行為未定義。
  2. 避免 return a - b 整數溢位,改用 Integer.compare(a, b)。
  3. Comparator 實作類別宜宣告為 static final 或單例,避免重複建立物件。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved