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

Java 比較器核心:Comparable 與 Comparator 區別、實現與最佳實踐

     編輯:Java 綜合教學

Java 比較器核心:Comparable 與 Comparator 區別、實現與最佳實踐

Java 提供兩大排序介面:Comparable<T>(內部比較)與 Comparator<T>(外部比較器)。本文通過完整代碼範例解析兩者定義、使用場景、策略模式應用與選型建議。

1. Comparable<T>:自然順序

public interface Comparable<T> {
    int compareTo(T o);
}
  • 類別**自身實現**,表示「我會跟同類比大小」。
  • 實現後,`List` 可直接 `Collections.sort(list)`、`Arrays.sort(array)`。
  • 返回值語意:負數=小於、0=等於、正數=大於。

範例:Student 按年齡→姓名排序

public class Student implements Comparable<Student> {
    private String name;
    private int age;
    // 構造器、getter/setter 省略

    @Override
    public int compareTo(Student other) {
        if (this.age != other.age) return Integer.compare(this.age, other.age);
        return this.name.compareTo(other.name);  // 年齡相同按姓名
    }
}

// 使用
List<Student> list = Arrays.asList(
    new Student("xiaosi", 24),
    new Student("sunny", 24),
    new Student("yoona", 21),
    new Student("kim", 27)
);
Collections.sort(list);
// 輸出:yoona(21) → sunny(24) → xiaosi(24) → kim(27)

2. Comparator<T>:策略模式外部比較器

public interface Comparator<T> {
    int compare(T o1, T o2);
    boolean equals(Object obj);  // 通常不需覆寫
}
  • **獨立類別**實現,不修改被比較類別(符合開閉原則)。
  • 一個類別可擁有多種比較策略(按姓名、按年齡、按ID倒序...)。
  • 調用:`Collections.sort(list, new MyComparator())`。

範例:Teacher 外部比較器

public class Teacher {
    private String name;
    private int age;
    // 省略 getter/setter
}

public class TeacherComparator implements Comparator<Teacher> {
    @Override
    public int compare(Teacher t1, Teacher t2) {
        if (t1.getAge() != t2.getAge()) return Integer.compare(t1.getAge(), t2.getAge());
        return t1.getName().compareTo(t2.getName());
    }
}

// 使用
Collections.sort(teachers, new TeacherComparator());

3. 核心差異對照

維度ComparableComparator
實現位置實體類別內部獨立類別(外部)
修改實體類需修改源碼無需修改
比較策略數單一(自然順序)無限多(可插拔)
適用場景領域模型有明確預設排序多維度排序、第三方類、臨時排序
設計模式——策略模式
泛型靈活性綁定自身類型可比較任意類型

4. 進階用法:Lambda 與 Comparator 組合 (Java 8+)

  • 返回 `this.field - other.field` 整數溢出風險 → 改用 `Integer.compare(a, b)` 或 `Long.compare(a, b)`。
  • 未處理 `null` 導致 NPE → 用 `Comparator.nullsFirst/Last` 包裝。
    1. 上一篇文章:
    2. 下一篇文章:
    Copyright © 程式碼之家 All Rights Reserved