现在的位置: 首页 > 综合 > 正文

对java中集合类排序的解析

2012年12月01日 ⁄ 综合 ⁄ 共 1099字 ⁄ 字号 评论关闭
第一次写关于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时,就采用插入排序,从而保证算法的稳定性。

抱歉!评论已关闭.