Arrays.sort 实现原理 和 Collections.sort 实现原理(源码分析)

 
Arrays.sort(int [] a) /Arrays.sort(long[] a) /Arrays.sort(float[] a)/Arrays.sort(double[] a)/
源码如下:

public static void sort(int[] a) {

    DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);

}

点进去

static void sort(int[] a, int left, int right,

                     int[] work, int workBase, int workLen) {

        // Use Quicksort on small arrays 如果数组长度小于286 那就使用快排

        if (right - left < QUICKSORT_THRESHOLD) { // 286

            sort(a, left, right, true);

            return;

        }

...

}

If中再点进去

private static void sort(int[] a, int left, int right, boolean leftmost) {

        int length = right - left + 1;

        // Use insertion sort on tiny arrays

        if (length < INSERTION_SORT_THRESHOLD) {  // 如果长度小于47 那么使用插入排序

 ...

}

}

总结: 理论上使用双轴快速排序,如果数组小于286 就使用经典快速排序,如果小于47 就使用插入排序,否则使用双轴快速排序

2. Arrays.sort(short[] a) /Arrays.sort(char[] a) /Arrays.sort(byte[] a) 

public static void sort(short[] a) {

        DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);

}

点进去:

static void sort(short[] a, int left, int right,

                     short[] work, int workBase, int workLen) {

        // Use counting sort on large arrays  大于1006就使用 counting sort(计数排序)

        if (right - left > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { // 大于1006

           ...

        } else { // Use Dual-Pivot Quicksort on small arrays //使用双轴快排

            doSort(a, left, right, work, workBase, workLen);

        }

 }

点进去doSort

 private static void doSort(short[] a, int left, int right,

                               short[] work, int workBase, int workLen) {

        // Use Quicksort on small arrays  // 小于286使用快速排序

        if (right - left < QUICKSORT_THRESHOLD) {

            sort(a, left, right, true); //当然这里再点进去就又回去了,即小于47 用插入排序

            return;

        }

}

总结: 如果数组长度大于1006 则使用计数排序, 小于286使用经典快速排序, 小于47 使用插入排序(比int 类的多了个1006)

 

3 . Arrays.sort(Object[] a) 

 public static void sort(Object[] a) {

        if (LegacyMergeSort.userRequested) //如果设置了归并排序为true

            legacyMergeSort(a);

        else //否则使用TimeSort(结合了归并排序和插入排序)

            ComparableTimSort.sort(a, 0, a.length, null, 0, 0);

}

LegacyMergeSort.userRequested 可以通过如下设置(类似保存jdk生成的代理类一样

System.setProperty(“sun.misc.ProxyGenerator.saveGeneratedFiles ”, “true”))

 

System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");

 

 

4 . Collections.sort(List<T> list)

源码如下:

@SuppressWarnings("unchecked")

    public static <T extends Comparable<? super T>> void sort(List<T> list) {

        list.sort(null);

}

点进去(以实现类ArrayList 来举例)

@Override

    @SuppressWarnings("unchecked")

    public void sort(Comparator<? super E> c) {

        final int expectedModCount = modCount;

        Arrays.sort((E[]) elementData, 0, size, c); //重点

        if (modCount != expectedModCount) {

            throw new ConcurrentModificationException();

        }

        modCount++;

    }

再点进去:

 public static <T> void sort(T[] a, int fromIndex, int toIndex,

                                Comparator<? super T> c) {

        if (c == null) { //比较器传入的为空

 

// 是否设置了LegacyMergeSort.userRequested为true 如果设置了则使用归并排序,如果未设置则使用TimSort

            sort(a, fromIndex, toIndex);  

        } else {

            rangeCheck(a.length, fromIndex, toIndex);  //检查是否越界

            if (LegacyMergeSort.userRequested)

                legacyMergeSort(a, fromIndex, toIndex, c);

            else

                TimSort.sort(a, fromIndex, toIndex, c, null, 0, 0);

        }

}

总结:

Collections.sort 里调用的传入的list 的sort 方法, 而ArrayList.sort 调用的Arrays.sort, Arrays.sort里  看是否设置了LegacyMergeSort.userRequested为true 设置了则使用归并排序,没有设置则使用TimSort
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值