對java中集合類排序的解析

第一次寫關於java源碼解析的文章,初窺門徑,貽笑大方。

整體的架構,java.util.Collections類,它裏面實現了對列表排序的功能,提供了一個靜態的sort方法,接受一個列表和一個Comparator接口的實例,這個方法的大致實現步驟如下

  1. 把列表轉換爲對象數組。
  2.  通過Array的sort方法來對數組進行排序,出入Comparator接口的實例。
  3. 把排好序的數組的數據根據設置回到原來的列表對象中去。

算法的骨架固定,而比較的方法依賴於傳入的Comparator接口的實例,內部通過這個接口來回調具體的實現。

下面這段話將Collections的排序委託給了Array

public static <T> void sort(List<T> list, Comparator<? super T> c) {
        Object[] a = list.toArray();
        Arrays.sort(a, (Comparator)c);
        ....}

數組中排序的方法如下

 public static <T> void sort(T[] a, Comparator<? super T> c) {
        if (LegacyMergeSort.userRequested)
            legacyMergeSort(a, c);
        else
            TimSort.sort(a, c);
    }
一般會採用TimSort中的sort方法進行排序,依然依賴於傳入的Comparator的具體實現

Comparator接口的對象必須實現Compare(Objet obj1,Object obj 2)方法,在該方法中若boj1邏輯上大於obj2,則返回正值,若二者相等則返回0,若obj1邏輯上小於obj2則返回負值.而在TimeSort中,具體的比較策略採用的是mergeSort(歸併排序)和binarySort(插入排序)混合的策略。由下面代碼可知

 // If array is small, do a "mini-TimSort" with no merges
        if (nRemaining < MIN_MERGE) {
            int initRunLen = countRunAndMakeAscending(a, lo, hi, c);
            binarySort(a, lo, hi, lo + initRunLen, c);
            return;
        }
// Push run onto pending-run stack, and maybe merge
            ts.pushRun(lo, runLen);
            ts.mergeCollapse();


採用遞歸的方法進行歸併排序,當遞歸的序列長度小於MIN_Merget  = 32時,就採用插入排序,從而保證算法的穩定性。




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