| 介面 | 套件 | 方法 | 適用場景 | 優缺點 |
Comparable<T> | java.lang | compareTo(T o) | 類別自然排序 (單一、固定規則) | 侵入式修改類別、只能有一種排序 |
Comparator<T> | java.util | compare(T o1, T o2) | 外部定義、多種排序策略 | 非侵入式、靈活、可組合 (Java 8+) |
實作 Comparable:老鼠體重/速度排序
class Mouse implements Comparable<Mouse> {
int weight;
int speed;
@Override
public int compareTo(Mouse other) {
// 先比體重,體重相同比速度
if (this.weight != other.weight)
return Integer.compare(this.weight, other.weight);
return Integer.compare(this.speed, other.speed);
}
}
// 使用
Mouse[] mice = ...;
Arrays.sort(mice); // 直接排序,無需額外參數
實作 Comparator:多種排序策略
// 按體重升序
Comparator<Mouse> byWeight = (m1, m2) -> Integer.compare(m1.weight, m2.weight);
// 按速度降序
Comparator<Mouse> bySpeedDesc = (m1, m2) -> Integer.compare(m2.speed, m1.speed);
// 組合:體重升序,體重相同則速度降序
Comparator<Mouse> composite = byWeight.thenComparing(bySpeedDesc);
// 使用
Arrays.sort(mice, composite);
Arrays.sort 完整用法速查
// 1. 基本型別陣列
int[] nums = {4, 1, 3, -23};
Arrays.sort(nums); // [-23, 1, 3, 4]
// 2. 字串陣列 (預設:大寫優先,字典序)
String[] strs = {"z", "a", "C"};
Arrays.sort(strs); // [C, a, z]
// 3. 忽略大小寫
Arrays.sort(strs, String.CASE_INSENSITIVE_ORDER); // [a, C, z]
// 4. 反向排序
Arrays.sort(strs, Collections.reverseOrder()); // [z, a, C]
// 5. 忽略大小寫 + 反向
Arrays.sort(strs, String.CASE_INSENSITIVE_ORDER);
Collections.reverse(Arrays.asList(strs)); // [z, C, a]
// 6. 物件陣列 + Comparator
User[] users = ...;
Arrays.sort(users, Comparator.comparing(User::getAge).reversed());
進階技巧:Comparator 靜態工廠方法 (Java 8+)
Comparator<User> c = Comparator
.comparing(User::getDept) // 主排序:部門
.thenComparing(User::getHireDate) // 次排序:入職日期
.thenComparing(User::getSalary, Comparator.reverseOrder()) // 薪資降序
.nullsLast(Comparator.naturalOrder()); // Null 值排最後
users.sort(c); // List 原地排序
// 或
Arrays.sort(users, c); // 陣列排序
常見陷阱與最佳實踐
- 避免減法溢位:
return a - b 可能溢位,改用 Integer.compare(a, b)
- Null 安全:使用
nullsFirst/Last 或 Objects.compare
- 穩定排序:
Arrays.sort 對物件使用 TimSort (穩定),基本型別用 Dual-Pivot Quicksort (不穩定)
- 效能:基本型別陣列排序比物件陣列快 (無裝箱/解箱、緩存友好)
總結選型建議
- 類別有明確「自然順序」 (如 ID、時間) → 實作
Comparable
- 需要多種排序、或無法修改類別 (第三方庫) → 用
Comparator
- Java 8+ 專案 → 優先用
Comparator.comparing 鏈式 API
- 高效能場景 → 考慮基本型別陣列 + 索引間接排序
掌握這兩大介面與現代 API,讓排序代碼既優雅又高效。
- 上一篇文章: Java 權重演算法實作:廣告加權隨機展示策略
- 下一篇文章: Java 實體類與 JSON 互轉最佳實務:Jackson 註解驅動與型別安全
Copyright ©
程式碼之家 All Rights Reserved