Java记录 -67- 深入剖析Collections的sort方法

来源:互联网 发布:mysql float 转换int 编辑:程序博客网 时间:2024/06/05 06:46

Collections类可以将存储与List中的元素进行排序,可以按照针对元素的排序方法进行排序,也可以按照指定的排序类进行排序。


Collections类提供了两个静态的sort方法:

  1. sort(List<T> list)

  2. sort(List<T> list, Comparator<? super T> c)

第一个方法是直接将List中的元素进行排序,排序方法需要List中存储的元素来提供,即存储的元素要是可排序的;

第二个方法除了提供要排序的List外,还需要提供一个指定的排序类,来指定排序规则,该List中存储的元素可不实现可排序接口。


从源代码查看它们具体的实现:

public static <T extends Comparable<? super T>> void sort(List<T> list) {    Object[] a = list.toArray();    Arrays.sort(a);    ListIterator<T> i = list.listIterator();    for (int j=0; j<a.length; j++) {        i.next();        i.set((T)a[j]);    }}public static <T> void sort(List<T> list, Comparator<? super T> c) {    Object[] a = list.toArray();    Arrays.sort(a, (Comparator)c);    ListIterator i = list.listIterator();    for (int j=0; j<a.length; j++) {        i.next();        i.set(a[j]);    }}

Collections的两个sort方法分别调用了Arrays的两个对应的sort方法,将排序的实现推给了Arrays去实现,下面我们看看Arrays中是怎么实现的sort方法:

    public static void sort(Object[] a) {        Object[] aux = (Object[])a.clone();        mergeSort(aux, a, 0, a.length, 0);    }    private static void mergeSort(Object[] src,                  Object[] dest,                  int low,                  int high,                  int off) {        int length = high - low;    // Insertion sort on smallest arrays        if (length < INSERTIONSORT_THRESHOLD) {            for (int i=low; i<high; i++)                for (int j=i; j>low &&             ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)                    swap(dest, j, j-1);            return;        }        // Recursively sort halves of dest into src        int destLow  = low;        int destHigh = high;        low  += off;        high += off;        int mid = (low + high) >>> 1;        mergeSort(dest, src, low, mid, -off);        mergeSort(dest, src, mid, high, -off);        // If list is already sorted, just copy from src to dest.  This is an        // optimization that results in faster sorts for nearly ordered lists.        if (((Comparable)src[mid-1]).compareTo(src[mid]) <= 0) {            System.arraycopy(src, low, dest, destLow, length);            return;        }        // Merge sorted halves (now in src) into dest        for(int i = destLow, p = low, q = mid; i < destHigh; i++) {            if (q >= high || p < mid && ((Comparable)src[p]).compareTo(src[q])<=0)                dest[i] = src[p++];            else                dest[i] = src[q++];        }    }

不带比较器参数的Arrays.sort方法调用了不带比较器的mergeSort方法,在mergeSort的实现中调用了存储对象本身的compareTo方法,因此利用该方法进行sort排序的对象必须实现compareTo方法。

        public static <T> void sort(T[] a, Comparator<? super T> c) {        T[] aux = (T[])a.clone();        if (c==null)            mergeSort(aux, a, 0, a.length, 0);        else            mergeSort(aux, a, 0, a.length, 0, c);    }        private static void mergeSort(Object[] src,                  Object[] dest,                  int low, int high, int off,                  Comparator c) {        int length = high - low;            // Insertion sort on smallest arrays        if (length < INSERTIONSORT_THRESHOLD) {            for (int i=low; i<high; i++)            for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)                swap(dest, j, j-1);            return;        }        // Recursively sort halves of dest into src        int destLow  = low;        int destHigh = high;        low  += off;        high += off;        int mid = (low + high) >>> 1;        mergeSort(dest, src, low, mid, -off, c);        mergeSort(dest, src, mid, high, -off, c);        // If list is already sorted, just copy from src to dest.  This is an        // optimization that results in faster sorts for nearly ordered lists.        if (c.compare(src[mid-1], src[mid]) <= 0) {           System.arraycopy(src, low, dest, destLow, length);           return;        }        // Merge sorted halves (now in src) into dest        for(int i = destLow, p = low, q = mid; i < destHigh; i++) {            if (q >= high || p < mid && c.compare(src[p], src[q]) <= 0)                dest[i] = src[p++];            else                dest[i] = src[q++];        }    }

带比较器参数的Arrays.sort方法调用了带比较器的mergeSort方法,在mergeSort的实现中调用了比较器的compareTo方法,而没有调用存储对象本身的。只需指定一个比较器即可。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 新车交车检验表客户没签字怎么办 中铁快运职工拒绝提货要怎么办 奇瑞a3暖风水箱爆了怎么办 别人挖鱼塘占了我的山土怎么办 自己的鱼塘让别人强行占住了怎么办 公路扩路占地占了鱼塘怎么办? 玉米皮编垫子编好后玉米绳怎么办 入户门门框未预留纱窗位怎么办 门和墙有2cm缝隙怎么办 支座预埋钢板忘记埋了怎么办 做完线雕一边紧一边松怎么办 卖家把没发货的填写了单号怎么办 买的人民币白银亏了好多钱怎么办 带控制线的三相四线开关怎么办 覆膜除尘布袋风拉不动怎么办 家里装修把暖气管道打破了怎么办 冷水管与热水管接错了怎么办 磨砂皮的鞋子打湿变硬了怎么办 等离子淡化热处理层渗不够厚怎么办 寄快递快递公司把东西弄坏了怎么办 寄美国的快递客人拒绝清关怎么办 国际e邮宝几天没物流信息了怎么办 石家庄小学网上报名填错了怎么办 去医院看病不知道挂什么科怎么办 深水井深水泵埋了2米怎么办 请问我捡的手机不是我的指纹怎么办 宝宝把塑料子弹塞到了鼻子里怎么办 坐便池上面的小孔不出水怎么办 还没离职已经找好工作怎么办 因火车晚点而耽误下趟火车怎么办 在广州坐的士丢了东西怎么办 找兼职的话他要求交押金怎么办 08vip不给提现了怎么办 点击订阅号所收到内容字太大怎么办 我的小叶栀子花老是黄叶该怎么办? 联币金融倒闭了我投资的钱怎么办 新单位交养老保险不接收档案怎么办 高铁发车十小时没赶上怎么办 饿了么被阿里收购员工怎么办? 爱疯4s密码忘了怎么办 研究生论文盲审一直不出结果怎么办