第一次寫關於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時,就採用插入排序,從而保證算法的穩定性。