一、排序原理简介
1.数组Arrays.sort()排序原理
通过Java API文档知道,Arrays.sort()调用的是DualPivotQuicksort.sort()方法,如下代码片段所示:
public static void sort(int[] a) {
DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
}
DualPivotQuicksort.sort()排序算法是双枢轴快速排序,时间复杂度为O(n log(n)),具体排序代码参见JDK API文档DualPivotQuicksort类中的sort()方法。Arrays.sort()只能用于基本数据类型:int、short、byte、long、float、double、char的排序。
2.排序方法Arrays.sort(Object[])
根据元素的自然顺序对指定对象数组按升序进行排序。数组中的所有元素都必须实现 Comparable 接口。此外,数组中的所有元素都必须是可相互比较的(也就是说,对于数组中的任何 e1 和 e2 元素而言,e1.compareTo(e2) 不得抛出 ClassCastException)。该排序算法是一个经过修改的合并排序算法(其中,如果低子列表中的最高元素小于高子列表中的最低元素,则忽略合并)该排序算法的时间复杂度为O(n log(n)),且是稳定的排序算法:不会因调用 sort 方法而对相等的元素进行重新排序, 如果数组包含不可相互比较的 的元素(例如,字符串和整数)抛出ClassCastException,此方法主要用于集合排序Collections.sort(),其调用List接口中的sort()方法进行排序。
3.集合Collections.sort()排序原理
通过Java API文档知道,Collections.sort()有两个实现方法,如下代码片段所示:
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) {
list.sort(c);
}
代码中list.sort()方法调用的就是Arrays.sort(Object [])方法,如下代码片段所示:
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);
}
}
二、Comparable和Comparator接口
1. Comparable接口简介
Comparable 是内比较器接口,在比较排序时是以自身作为基对象与传入的对象进行大小比较。如果一个类实现了Comparable接口,那么说明该类支持按照指定规则(compareTo方法)进行大小比较:如果A.compareTo(B)返回小于零的数(负数),则说明A小于B;如果A.compareTo(B)返回等于零的数,则说明A与B相等;如果A.compareTo(B)返回大于零的数(正数),则说明A大于B。
2. Comparator接口简介
Comparator 是外比较器接口。若我们需要对某个对象集合进行排序,而该对象本身不支持排序(即没有实现Comparable接口);那我们可以创建一个该对象的外比较器来进行排序。这个比较器只需要实现Comparator接口,重写Comparator接口的compare()方法(即指定对象的大小比较规则)。然后通过该比较器对类进行排序。int compare(T o1, T o2)和上面的A.compareTo(B)类似,如果int compare(T o1, T o2)返回小于零的数,则说明o1小于o2;如果int compare(T o1, T o2)返回等于零,则说明o1等于o2;如果int compare(T o1, T o2)返回大于零的数,则说明o1大于o2。
3.Comparable和Comparator本质
Comparable和Comparator接口本身并不具备排序功能,它只是进行了两个对象按照指定规则的大小比较,Collections.sort()和List.sort()均调用了Arrays.sort(Object[])方法对实现了Comparable接口的对象集合进行排序,如果对象实现的比较规则compareTo()不满足要求,或者需要传入自定义的比较规则时,就可以将外比较器Comparator作为参数传入排序方法中,Collections.sort()和List.sort()均支持可选择的外部排序参数。
4.Comparable排序示例
创建POJO对象Student类:
public class Student implements Comparable<Student>{
private String name;
private int age;
private int score;
public Student() {
}
public Student(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age