Collections.sort() in JDK1.6

本文主要介绍了Collections.sort方法在JDK1.6中的源码实现(JDK版本1.6.0_45)

1.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.set(a[j]);
        }
    }

首先这个方法将list转换为数组并调用了Arrays.sort()方法(至于这个Comparator是一种比较器,外界需要实现其compare方法;还有一种是Comparable,实现的是compareTo方法,有兴趣的可以研究一下。),在对数组进行排序之后,通过迭代器将排序结果更新到list中。(迭代器的相关知识不做介绍了,因为我也没看这部分的源码)

2.Arrays.sort()

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);
    }

先是利用Object的clone方法创建了一个a的副本对象(Object的clone方法为浅克隆方式,它只克隆了自身对象和对象内部实例变量的地址引用。也就是说在堆内存只是创建了a自身副本对象,而在栈内存中创建了对象内部实例变量的地址引用副本。)

判断比较器c存不存在,实际上mergeSort(aux, a, 0, a.length, 0)和mergeSort(aux, a, 0, a.length, 0, c)内部实现方式一样,只是如果比较器c(Comparator)不存在,mergeSort(aux, a, 0, a.length, 0)内部会使用Comparable比较器的compareTo方法。

3.mergeSort(归并排序)

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++];
        }
    }

这一部分代码比较多,首先程序会通过判断length < INSERTIONSORT_THRESHOLD(INSERTIONSORT_THRESHOLD默认为7),如果数组长度小于7,会使用直接插入排序算法。

这个上张图解释一下,图片来源https://www.cnblogs.com/chengxiao/p/6103002.html

现在来看一下代码,代码很简单,两个循环,外层循环遍历数组(图中的待排序序列),内层循环将每一次待排序的值按顺序放入有序序列中(只是一种表达方式,实际上就是交换),比如图中在对1进行插入时,会先跟前一个元素9进行比较,1<9,交换位置,然后1再跟前一个元素3比较,1<3,交换位置。

要是数组长度不小于7呢,就会使用归并排序算法啦,有关归并排序算法的介绍可以参考这篇博客https://www.cnblogs.com/chengxiao/p/6194356.html,这里就不贴图了。

归并排序的核心思想呢就是分而治之嘛,说起来挺容易的哈!

下面代码通过采用递归方式实现分的思想,分到最后还是用了直接插入排序,这个有个地方需要注意一下,就是src和dest的参数位置(数组的起止位置就不用说了吧!),在调用递归时,是将src数组作为排序对象进行排序的,然后dest数组是依据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);

现在分完了,怎么治呢?前面所说的dest数组是依据src进行排序在此进行了体现,最开始说的两个mergeSort方法的不同之处(比较器)在这也能看出。

首先有一种特别友好的情况,那就是分完的前半部分最大的那个正好小于等于后半部分最小的元素(这只是递归过程中的一个分支),那么皆大欢喜,src数组已经是有序的了,只需将src数组复制到目标数组中(System.arraycopy具体用法自行上网查吧)。

// 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++];
}

其他情况怎么处理呢,这个再贴张图,图片来源https://blog.csdn.net/ghsau/article/details/42060651,这篇博客是我参考的博客,大家也可以看看。

思想很简单,循环整个数组,比较左边的元素和右边的元素,谁小把谁放到dest中(再次重申,这只是递归过程中的一个分支),然后移动对应指针,直到src所有元素都放入到dest中。

例如一开始是2和1进行比较,1小放入dest中,p不变,q指向5(看做指针),i指向下一个位置;2和5比较,2小放入dest中,p指向3,q不变,i指向下一个位置,以此类推,直到循环结束。

到这里算是写完了,写的可能不好,刚毕业大学生水平有限,工作之后的第一篇博客,请原谅我一些地方的无知;如果有什么错误,请一定要指出,万分感谢,您的意见是我成长的催化剂。

下面整理一下参考资料。

https://blog.csdn.net/ghsau/article/details/42060651

https://www.jianshu.com/p/1efc3aa1507b

https://www.cnblogs.com/chengxiao/p/6103002.html

https://www.cnblogs.com/chengxiao/p/6194356.html

后面如果有机会,会写一篇jdk1.7之后有关sort这一部分的博客。

疑问:mergeSort中有一个off参数,个人理解是限制排序集合的区域范围(起止怎么确定的。。。)?JDK1.7中sort方法中的paramInt1和paramInt2是不是起到了类似的功能?

原文地址:https://www.cnblogs.com/java-meng/p/9522948.html

时间: 2024-10-12 20:08:21

Collections.sort() in JDK1.6的相关文章

jdk1.7和jdk1.6的Collections.sort方法不一样

Java代码 Collections.sort(list, new Comparator<AAAVo>() { @Override public int compare(AAAVo vo1, AAA vo2) { if(vo1==null||vo2==null){ return 0; } if(Integer.valueOf(vo1.getCouponValue())<Integer.valueOf(vo2.getCouponValue())){ if(vo1.getConsumeTim

java基础——Collections.sort的两种用法

Collections是一个工具类,sort是其中的静态方法,是用来对List类型进行排序的,它有两种参数形式: public static <T extends Comparable<? super T>> void sort(List<T> list) { list.sort(null); } public static <T> void sort(List<T> list, Comparator<? super T> c) {

Java Collections.sort方法对list集合排序

1.排序测试类 package com.ljq.test; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class UserSort { public static void main(String[] args) { List<User> userList =new ArrayList<User&g

java Collections.sort()实现List排序自定义方法

方法一: package testSimple; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class testCollectionSort { public static void main(String[] args) { List<TblPowerGroup> list = new ArrayLis

java List 排序 Collections.sort() 对 List 排序

实体类: class User { String name; String age; public User(String name,String age){ this.name=name; this.age=age; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getName() { return name; } public

java中Collections.sort排序详解

Comparator是个接口,可重写compare()及equals()这两个方法,用于比价功能:如果是null的话,就是使用元素的默认顺序,如a,b,c,d,e,f,g,就是a,b,c,d,e,f,g这样,当然数字也是这样的.compare(a,b)方法:根据第一个参数小于.等于或大于第二个参数分别返回负整数.零或正整数.equals(obj)方法:仅当指定的对象也是一个 Comparator,并且强行实施与此 Comparator 相同的排序时才返回 true. Collections.so

升序 Collections.sort(list) 降序 Collections.reserve(list) 随机 Collections.shuffle(list)

1 package Day28ketangzuoye; 2 3 import java.util.ArrayList; 4 import java.util.Collections; 5 import java.util.Comparator; 6 import java.util.HashSet; 7 import java.util.List; 8 import java.util.Scanner; 9 10 public class DemoChars{ 11 12 public stat

Collections.sort方法对list排序的两种方式

Collections.sort( )分为两部分,一部分为排序规则,一部分为排序算法 . 规则用来判断对象,算法则考虑如何进行排序 对于自定义对象,sort()不知道规则,所以无法比较,这种情况下一定要定义排序规则.方式有两种: 第一种,java.lang下面的一个接口:Comparable.可以让自定义对象实现一个Comparable接口,这个接口只有一个方法comparableTo(Object o) 其规则是当前对象与o对象进行比较,返回一个int值,系统根据此值进行排序. 如当前对象>o

java Collections.sort()实现List排序的默认方法和自定义方法

1.java提供的默认list排序方法 主要代码: List<String> list = new ArrayList();list.add("刘媛媛"); list.add("王硕");list.add("李明");list.add("刘迪");list.add("刘布"); //升序Collections.sort(list,Collator.getInstance(java.util.Lo