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

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方法,而没有调用存储对象本身的。只需指定一个比较器即可。

时间: 2024-12-19 10:44:21

Java记录 -67- 深入剖析Collections的sort方法的相关文章

【Java】Collections中sort方法Comparator的重写

很多人只会用Collections中不带比较器Comparator的sort方法完成一些对存储整形Integer的动态数组ArrayList的简单排序,包括我之前,此前仅仅在<[Java]Java中的Collections类--Java中升级版的数据结构>(点击打开链接)介绍Collections中sort方法的简单用法. igz 面对eclipse所给出的说明,根本就不知道这个sort方法如何重写,如果我对一个存储Student类的动态数组进行以学生的学号为根据,姓名为根据进行排序,那该如何

Collections中sort()方法源代码的简单分析

Collections的sort方法代码: 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.

java的collections的sort的API

这里是有关JAVA的collections的sort 的有关知识 一: import java.util.ArrayList; import java.util.Collections; import java.util.List; public class SortListDSemo2 { public static void main(String[] args) { List<Point> list=new ArrayList<Point>(); list.add(new P

Java使用sort()方法对数组进行排序

1 package com.yzy.test; 2 3 import java.util.Arrays; 4 5 public class Test { 6 7 /** 8 * @param args 9 */ 10 public static void main(String[] args) { 11 int[] array = { 43, 64, 21, 6565, 3424, 22, 6523, 345 }; 12 Arrays.sort(array); 13 for (int i : a

sort方法和自定义比较器的写法

摘要 在做一些算法题时常常会需要对数组.自定义对象.集合进行排序. 在java中对数组排序提供了Arrays.sort()方法,对集合排序提供Collections.sort()方法.对自定义对象排序时要自己重写比较器,对象数组则调用Arrays.sort(),对象集合则调用Collections.sort().两个方法默认都是升序,也可以重写比较器,实现降序. 对数组排序 sort函数模板, 以int型数组为例: Arrays.sort(int[] a, Comparator<Integer>

Java基础集合类总结之Collections.sort()

面试中被问到,集合类中的排序方法是怎么实现的?没有回答上来,故而总结如下:你知道么? 前提:在eclipse中对于自己的代码可以通过按住Ctrl的同时单击名称跳入相应源码中.但eclipse默认没有添加java源代码目录,比如点击Thread会提示source not found,而在开发中了解Java源代码又是技术成长必要的.jdk默认是附带源码zip包的(jdk按装目录下的src.zip文件),我们可以通过添加源码在eclipse中查看.在提示source not found界面,点击Att

Java中自定义对象使用Collections工具类中的Sort方法

Collections工具类中的sort方法有两种形式: (1) sort(List<T> list) (2) sort(List<T> list, Comparator<? super T> c) 第一种方法中List类型的对象必须实现Comparable接口,此外,List中的元素必须可比较. 我们先定义类 package com.dongye.sort; import java.util.ArrayList; import java.util.Collection

Java 容器 &amp; 泛型:四、Colletions.sort 和 Arrays.sort 的算法

Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket 本来准备讲 Map集合 ,还是喜欢学到哪里总结吧.最近面试期准备准备,我是一员,成功被阿里在线笔试秒杀回绝.平常心,继续努力.这次带来 Collections 和 Arrays 类中的经典算法剖析. 一.Colletions和Arrays Collentions 此类完全是服务容器的”包装器“.提供了一些操作或者返回容器的静态方法.而Arrays是用来操作数组的各种方法.其中它们的联系在于其中的So

(转载)Java 容器 &amp; 泛型:四、Colletions.sort 和 Arrays.sort 的算法

讲 Map集合 ,还是喜欢学到哪里总结吧.最近面试期准备准备,我是一员,成功被阿里在线笔试秒杀回绝.平常心,继续努力.这次带来 Collections 和 Arrays 类中的经典算法剖析. 一.Colletions和Arrays Collentions 此类完全是服务容器的”包装器“.提供了一些操作或者返回容器的静态方法.而Arrays是用来操作数组的各种方法.其中它们的联系在于其中的Sort方法,也就是这次博客的主题. 二.插入,快速.归并基本算法 ① 插入排序 {a1},{a2,a3,a4