| 入口方法 | 適用對象 | 底層演算法 | 備註 |
Collections.sort(List) | List | TimSort(歸併+插入混合) | 元素必須實現 Comparable |
Collections.sort(List, Comparator) | List | TimSort | 傳入外部比較器 |
Arrays.sort(Object[]) | 陣列 | TimSort | 運行時檢查 Comparable |
TreeSet/TreeMap | 有序集合 | 紅黑樹 | 插入即排序,構造器可傳 Comparator |
實戰一:中文拼音排序(Comparator 策略)
// 核心:Collator.getInstance(Locale.CHINA) 實現漢字拼音比較
public class ChineseComparator implements Comparator<String> {
private final Collator collator = Collator.getInstance(Locale.CHINA);
@Override public int compare(String o1, String o2) {
return collator.compare(o1, o2);
}
}
// 使用
List<String> names = Arrays.asList("張三", "李四", "王五");
Collections.sort(names, new ChineseComparator());
// 結果:李四、王五、張三(按拼音 l, w, z)
實戰二:多字段組合排序(Comparator 鏈式)
// 先按部門升序,再按薪資降序
Comparator<Employee> combo = Comparator
.comparing(Employee::getDept)
.thenComparing(Employee::getSalary, Comparator.reverseOrder());
Collections.sort(list, combo);
實戰三:對象實現 Comparable(自然順序)
public class User implements Comparable<User> {
private String name;
// getter/setter...
@Override
public int compareTo(User o) {
return Collator.getInstance(Locale.CHINA).compare(this.name, o.name);
}
}
// 直接排序,無需傳 Comparator
Collections.sort(userList);
TreeSet<User> set = new TreeSet<>(); // 自動按 name 排序
源碼深度剖析:Arrays.sort → TimSort
關鍵流程
Collections.sort(list) → 轉陣列 → Arrays.sort(array) → mergeSort()
- TimSort 核心:
- 小區間(< 7)用二分插入排序。
- 大區間遞歸分治歸併排序。
- 合併前檢查
src[mid-1] <= src[mid],已有序則直接 arraycopy 跳過合併。
- Comparable 路徑:強轉
(Comparable) obj 調用 compareTo,未實現拋 ClassCastException。
- Comparator 路徑:調用傳入
c.compare(o1, o2),無強轉風險。
TreeSet/TreeMap 源碼揭秘
// TreeSet 構造器
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator)); // 內部封裝 TreeMap
}
// TreeMap.put 核心邏輯
Comparator<? super K> cpr = comparator;
if (cpr != null) {
// 使用 Comparator 比較,決定左/右子樹
cmp = cpr.compare(key, t.key);
} else {
// 使用 Comparable 比較
@SuppressWarnings("unchecked")
Comparable<? super K> k = (Comparable<? super K>) key;
cmp = k.compareTo(t.key);
}
// 紅黑樹插入平衡:fixAfterInsertion(e)
避坑指南與最佳實踐
- 空指針安全:Comparator 鏈式寫法自動處理 null;手寫 compare 時先判 null。
- 一致性原則:
compareTo 與 equals 應保持一致(x.compareTo(y)==0 ⟺ x.equals(y)),否則 TreeSet/TreeMap 行為異常。
- 序列化注意:實現 Comparable 的類建議實現
Serializable,避免分布式傳輸問題。
- 性能選擇:單一固定順序用 Comparable;多策略、第三方類、組合排序用 Comparator。
- 上一篇文章: Java 分支結構核心筆記:if-else、switch-case 完全指南與避坑技巧
- 下一篇文章: Spring MVC Controller 間跳轉完全指南:redirect、forward、參數傳遞與 Flash 屬性最佳實踐
Copyright ©
程式碼之家 All Rights Reserved