JDK8自带的两种排序Arrays.sort()和Collections.sort()

JDK8自带的两种排序 Arrays.sort和Collections.sort


Arrays.cort()是数组的排序方法,Collections.sort()是集合的排序方法,两个方法我们在平时都经常用到,给我们带来了便利。



一、Arrays.cort()

Arrays.sort(数组名);
Arrays.sort(数组名 ,int fromIndex, int toIndex);

这两个方法在排序中用到的频率最高,默认是升序排序,当我们需要默认排序时,就需要花点功夫了。


Arrays.cort()自定义排序
通过自定义一个类实现Comparator接口的compare()方法,再作为比较器传参,就可以现在自定义排序了。

public class test1 {
     
    public static void main(String args[]) throws IOException {
     
        //注意,要想改变默认的排列顺序,不能使用基本类型(int,double, char),而要使用它们对应的类
        Integer[] arr = {
     9, 8, 7, 2, 3, 4, 1, 0, 6, 5};
        //定义一个自定义类MyComparator的对象
        Comparator cmp = new Comparator() {
     
            @Override
            public int compare(Object o1, Object o2) {
     
                return (Integer)o1 > (Integer)o2 ? -1 :1;
            }
        };
        Arrays.sort(arr,cmp);
        System.out.println(Arrays.toString(arr));
    }
}

Arrays.cort()逆序排序

Integer[] a = {
     9, 8, 7, 2, 3, 4, 1, 0, 6, 5}; 
Arrays.sort(a,Collections.reverseOrder()); //Collections.reverseOrder()在方法调用返回一个比较器,它强行上实现Comparable接口的对象的集合的自然顺序相反。
System.out.println(Arrays.toString(a));


二、Collections.cort()

List<Integer> intList = Arrays.asList(33, 24, 18, 6, 9, 99);
Collections.sort(intList);

Collections.sort()自定义排序

Collections.sort(personList, new Comparator<Person>() {
     

            @Override
            public int compare(Person p1, Person p2) {
     
                return p1.getAge() > p2.getAge() ? 1 : -1;//升序
            }

 });


三、面试重点:源码分析

一、Arrays.sort()

基本类型:采用调优的快速排序;
对象类型:采用改进的归并排序。

1、基本类型
数组长度小于47的时候是用直接插入算法,大于47并且小于286是采用双轴快速排序,大于286如果连续性好「也就是元素大多有序,有一个flag专门用来记录数组元素的升降次数,代表这个数组的连续性」采用的是归并排序,否则还是依旧采用双轴快速排序。
小于286(小于47/大于47并且小于286)

private static void sort(int[] a, int left, int right, boolean leftmost) {
     
        int length = right - left + 1;

        // 长度小于47,使用直接插入排序
        if (length < INSERTION_SORT_THRESHOLD) {
     
            if (leftmost) {
     
                /*
                 * Traditional (without sentinel) insertion sort,
                 * optimized for server VM, is used in case of
                 * the leftmost part.
                 */
                for (int i = left, j = i; i < right; j = ++i) {
     
                    int ai = a[i + 1];
                    while (ai < a[j]) {
     
                        a[j + 1] = a[j];
                        if (j-- == left) {
     
                            break;
                        }
                    }
                    a[j + 1] = ai;
                }
            }
            //长度大于47小于286
            else {
     
                //双轴快速排序
            }

大于等于286

static void sort(int[] a, int left, int right,
                     int[] work, int workBase, int workLen) {
     
        // 小于286排序
        if (right - left < QUICKSORT_THRESHOLD) {
     
            sort(a, left, right, true);
            return;
        }

        /*
         * Index run[i] is the start of i-th run
         * (ascending or descending sequence).
         */
        int[] run = new int[MAX_RUN_COUNT + 1];
        int count = 0; run[0] = left;

        //检查数组是否接近排好序
        for (int k = left; k < right; run[count] = k) {
     
            if (a[k] < a[k + 1]) {
      // 上升
                while (++k <= right && a[k - 1] <= a[k]);
            } else if (a[k] > a[k + 1]) {
      // 下降
                while (++k <= right && a[k - 1] >= a[k]);
                for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
     
                    int t = a[lo]; a[lo] = a[hi]; a[hi] = t;
                }
            } else {
      // 相等
                for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
     
                    if (--m == 0) {
     
                        sort(a, left, right, true);
                        return;
                    }
                }
            }

            /*
             *连续性不好,
             *依然使用快速排序.
             */
            if (++count == MAX_RUN_COUNT) {
     
                sort(a, left, right, true);
                return;
            }
        }

        //检查特殊情况
        // Implementation note: variable "right" is increased by 1.
        if (run[count] == right++) {
      // The last run contains one element
            run[++count] = right;
        } else if (count == 1) {
      // The array is already sorted
            return;
        }

    		 /*
             *连续性好,
             *使用归并排序.
             */
    		.............
        }
    }
    

2、对象类型

TimSort.sort()

 public static void sort(Object[] a) {
     
        if (LegacyMergeSort.userRequested)//如果设置了归并排序为true
            legacyMergeSort(a);
        else//否则使用TimeSort(结合了归并排序和插入排序)
            ComparableTimSort.sort(a, 0, a.length, null, 0, 0);
    }

当待排序元素小于32个时,采用二分插入排序,是插入排序的一种改进。
当待排序元素大于等于32个时,进行归并排序。

二、Collectiom.sort()

 @SuppressWarnings({
     "unchecked", "rawtypes"})
    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()中的TimSort.sort()


总结:Arrays.sort()分为基本数据类型和对象类型。Collections.sort()是先转换为数组,再调用Arrays.sort(),也就是对象类型。


哪里写得不好或者想讨论的小伙伴欢迎留言哦!

你可能感兴趣的:(java,排序)