Collections.sort()方法解析

首先注意这里调用sort方法的是Collections类,他是集合框架中的一员,其中实现了大量的工具方法,有时间可以自行查看:
这里写图片描述

下面是一个简单的测试类:

import java.util.*;

/**
 * Created by Admin on 2017/3/7.
 */
public class CollectionTest {

    public static void main(String[] args){
        List<Integer> list_1 = new ArrayList<Integer>(Arrays.asList(2,1,4,8,5));
        System.out.println("before sort:"+list_1.toString());

        Collections.sort(list_1);
        System.out.println("after sort:"+list_1.toString());
    }

}

其中创建了一个ArrayList实例去测试sort()方法,执行结果如下:
这里写图片描述


开始进入正题,我们首先查看Collections中sort方法的源代码:

public static <T extends Comparable<? super T>> void sort(List<T> list) {
        list.sort(null);//传入参数还可以是一个Comparator对象,但是也有一定的要求
    }

其中牵扯了许多泛型,T表示要排序的序列中的包含类型,这里出现了一个要求,类型 T 必须实现 Comparable 接口,public final class Integer extends Number implements Comparable<Integer>,并且这个接口的类型是 T 或 T 的任一父类。这样声明后,T 的实例之间,T 的实例和它的父类的实例之间,可以相互比较大小。传入的参数为List类型。

这样,我们又开始查看List中的sort方法,只是为了让排序能继续进行,对数据类型进行 一些处理:

default void sort(Comparator<? super E> c) {
        Object[] a = this.toArray();//向上地获取数组对象
        Arrays.sort(a, (Comparator) c);//传入下一层
        ListIterator<E> i = this.listIterator();
        for (Object e : a) {
            i.next();
            i.set((E) e);//将数组对象类型还原
        }
    }

再次进入Arrays类的sort,此处传入的参数是Object的:

public static void sort(Object[] a) {
        //如果符合要求,直接对序列进行归并排序操作(legacyMergeSort),最后的归并排序代码可以自己看一下,我就不贴了
        //private static void mergeSort(Object[] src,Object[] dest,int low,int high,int off)
        if (LegacyMergeSort.userRequested)
            legacyMergeSort(a);
        else
            //否则,进入下一环节
            ComparableTimSort.sort(a, 0, a.length, null, 0, 0);
    }

在1.7之后,不再默认使用归并排序,LegacyMergeSort.userRequested被默认为false,也可以通过来更换

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

所以再再进入ComparableTimSort的sort(),别急,马上就完!
传入参数数组a,lo与hi为要执行排序序列的开始与结束位置,work是一个备用的空间,可以为其设置属性,在上面方法的调用中,我们并没有使用到work

static void sort(Object[] a, int lo, int hi, Object[] work, int workBase, int workLen) {
        assert a != null && lo >= 0 && lo <= hi && hi <= a.length;

        int nRemaining  = hi - lo;
        if (nRemaining < 2)//少于2个数字拿来排序,到这里才返回...有毒
            return;  // 0或1个数字总是排好序的(有点像放屁

        if (nRemaining < MIN_MERGE) {//MIN_MERGE的值为32
            int initRunLen = countRunAndMakeAscending(a, lo, hi);
            //大小小于32时,使用二叉排序!
            binarySort(a, lo, hi, lo + initRunLen);
            return;
        }

        ComparableTimSort ts = new ComparableTimSort(a, work, workBase, workLen);
        int minRun = minRunLength(nRemaining);//minRun值等于长度的一直除以2,直到小于MIN_MERGE
        do {
            // Identify next run
            int runLen = countRunAndMakeAscending(a, lo, hi);

            // If run is short, extend to min(minRun, nRemaining)
            if (runLen < minRun) {
                int force = nRemaining <= minRun ? nRemaining : minRun;
                binarySort(a, lo, lo + force, lo + runLen);
                runLen = force;
            }

            // Push run onto pending-run stack, and maybe merge
            ts.pushRun(lo, runLen);
            ts.mergeCollapse();

            // Advance to find next run
            lo += runLen;
            nRemaining -= runLen;
        } while (nRemaining != 0);

        // Merge all remaining runs to complete sort
        assert lo == hi;
        ts.mergeForceCollapse();
        assert ts.stackSize == 1;
    }

其中使用的二分查找与合并等种种过程,根据一个个条件优化操作。精华的地方慢慢品吧。稍后添加!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Collections.sort()是Java中用于对集合进行排序的方法。它可以对任何实现了Comparable接口的类进行排序,包括String和Integer等。使用Collections.sort()方法时,可以有两种方式进行排序。 第一种方式是使用默认排序规则进行排序。对于已经实现了Comparable接口的类,可以直接调用Collections.sort()方法传入待排序的集合参数,即可按照默认方式从小到大(正序)进行排序。例如,对一个List<String>进行排序,可以使用以下代码: Collections.sort(list); 第二种方式是自定义排序规则进行排序。如果不想使用默认的排序方式,可以通过传入一个Comparator对象来定义自己的排序规则。Comparator是一个函数式接口,可以使用Lambda表达式或匿名类的方式来实现。比如,对一个List<Integer>进行按照从大到小(逆序)进行排序,可以使用以下代码: Collections.sort(list, (a, b) -> b - a); 总而言之,Collections.sort()方法可以根据不同的需求,使用默认排序规则或自定义排序规则来对集合进行排序。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Java Arrays.sortCollections.sort排序实现原理解析](https://download.csdn.net/download/weixin_38657115/12743197)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Collections.sort的使用](https://blog.csdn.net/QGhurt/article/details/116118191)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值