第一次寫關於java源碼解析的文章,初窺門徑,貽笑大方。
整體的架構,java.util.Collections類,它裡面實現了對列表排序的功能,提供了一個靜態sort方法,接受一個列表和一個Comparator介面的執行個體,這個方法的大致實現步驟如下
- 把列錶轉換為對象數組。
- 通過Array的sort方法來對數組進行排序,出入Comparator介面的執行個體。
- 把排好序的數組的資料根據設定回到原來的列表對象中去。
演算法的骨架固定,而比較的方法依賴於傳入的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時,就採用插入排序,從而保證演算法的穩定性。