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

Java 集合排序兩大核心方案:Comparable 與 Comparator 完全指南

     編輯:Java 相關知識

兩種排序契約對比

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

compareTo 返回值規則速記

  • < 0:this < o(this 排前面)
  • == 0:this == o
  • > 0:this > o(this 排後面)

最佳實踐建議

  1. 實體類實現 Comparable 定義「自然順序」(如 ID、時間戳)。
  2. 業務多樣排序用 Comparator,配合 Java 8 Comparator.comparing... 鏈式 API,代碼可讀性極強。
  3. 避免在 compareTo 做複雜邏輯,保持單一職責;複雜排序拆分為多個 Comparator 組合。
  4. 注意 null 安全:Comparator.nullsFirst() / nullsLast() 處理空值。

總結

Comparable 定義對象固有順序,Comparator 提供靈活外部策略。Java 8 後推薦以 Comparator.comparing() 鏈式構建比較器,配合 Stream sorted() 實現聲明式排序,徹底替代匿名內部類時代。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved