源碼分析 Java 比較器的排序規則

話不多說,直接看代碼,從 Collections 的 sort 方法開始。

Collections 類帶有比較器的 sort 方法會進入到 List 接口的一個默認方法:

Collections.sort(dogs, new DogAgeComparator());
default void sort(Comparator<? super E> c) {
    Object[] a = this.toArray();
    Arrays.sort(a, (Comparator) c);
    ...
}

再進入到 Arrays 類的 sort 方法:

public static <T> void sort(T[] a, Comparator<? super T> c) {
    if (c == null) {
        sort(a);
    } else {
        if (LegacyMergeSort.userRequested)
            legacyMergeSort(a, c);
        else
            TimSort.sort(a, 0, a.length, c, null, 0, 0);
    }
}

如果有自定義的外部排序(Comparator),就會進入第 4 行的 else 語句塊中,其中的 LegacyMergeSort 排序已經被廢棄(如果你指定使用該方法也可以),現在用的是 TimSort 的排序方法,相比起舊版本直接使用 歸併排序 算法,新版本在此基礎上還引入了 “二分插入排序” 的優化。

接下來,因爲我們討論的主題是 Comparator 和 Comparable 中方法的返回值對排序結果的影響,新版本雖然優化了排序性能,但原本的思想不會有改變,所以我們採用舊版本排序代碼的分析。

LegacyMergeSort 的 mergeSort 算法中的實現了外部比較器 Comparator的代碼:
圖片
或者實現了 Comparable 接口的實現:
圖片
最爲關鍵的部分,第 4 行使用到的 compare 方法中的 dest[j-1]dest[j]調用結果 > 0 的條件下,會進行 swap,交換他們的位置。
圖片
看上面的圖片代碼, o1 代表的是暫時排在前面的元素,o2 代表排在後面的元素。

只要記住,return 值 > 0 的時候會交換 o1 和 o2 的位置,以此來實現你想要的排序規則。

最後,給兩個具體的實現代碼(重點看註釋部分!):
在這裏插入圖片描述
在這裏插入圖片描述

如果本篇文章有幫助到你的話,可以點個贊呀。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章