public interface Comparable<T> { public int compareTo(T o); }
public interface Comparator<T> { int compare(T o1, T o2); ... }
Comparable Demojava
import java.util.*; public class ComparableDemo { public static void main(String[] args) { List<Person> people=new ArrayList<>(); people.add(new Person(20,Person.MALE)); people.add(new Person(22,Person.FEMALE)); people.add(new Person(21,Person.FEMALE)); people.add(new Person(24,Person.MALE)); people.sort(null); // Collections.sort(people); for (Person person:people) { System.out.println(person); } } static class Person implements Comparable<Person> { int age; String gender; static final String MALE="male"; static final String FEMALE="female"; public Person(int age,String gender){ this.age=age; this.gender=gender; } @Override public String toString() { return "age: "+this.age+", gender: "+this.gender; } @Override public int compareTo(Person o) { return this.age-o.age; } } }
Comparator Demo算法
import java.util.*; public class ComparatorDemo { public static void main(String[] args) { List<Person> people=new ArrayList<>(); people.add(new Person(20,Person.MALE)); people.add(new Person(22,Person.FEMALE)); people.add(new Person(21,Person.FEMALE)); people.add(new Person(24,Person.MALE)); Comparator<Person> comparator=new Comparator<Person>() { @Override public int compare(Person o1, Person o2) { if (o1==null||o2==null) return 0; return o1.age-o2.age; } }; people.sort(comparator); // Collections.sort(people,comparator); for (Person person: people) { System.out.println(person); } } static class Person { int age; String gender; static final String MALE="male"; static final String FEMALE="female"; public Person(int age,String gender){ this.age=age; this.gender=gender; } @Override public String toString() { return "age: "+this.age+", gender: "+this.gender; } } }
Compartor:
//先從開始調用的地方開始看: Collections.sort(people);
轉到Collections的sort源碼:
//Collections.java public static <T extends Comparable<? super T>> void sort(List<T> list) { list.sort(null); }
這裏就能看到,其實Collections也是調用了list的sort方法:
//List.java 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方法ide
//Arrays.java public static <T> void sort(T[] a, Comparator<? super T> c) { if (c == null) { sort(a); } else { if (LegacyMergeSort.userRequested) legacyMergeSort(a, c); else TimSort.sort(a, 0, a.length, c, null, 0, 0); } } public static void sort(Object[] a) { if (LegacyMergeSort.userRequested) legacyMergeSort(a); else ComparableTimSort.sort(a, 0, a.length, null, 0, 0); } ... /** To be removed in a future release. */ private static void legacyMergeSort(Object[] a) { Object[] aux = 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; } .... // 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方法開始,因爲Compartor爲null,調用只有一個參數Object[] a的sort函數,而後根據預設好的系統參數:LegacyMergeSort.userRequested來判斷調用舊的歸併排序函數仍是調用一個更高性能的歸併排序算法TimSort,這裏只對legacyMergeSort進行分析,由於對於Comparable的調用過程來講基本一致,legacyMergeSort會調用mergeSort函數,在mergeSort函數中能夠看到:函數
... 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); ...會調用實現了Comparable接口的bean類的compareTo方法,所以若是沒有實現Comparable接口的類調用sort(null)函數會拋出錯誤
Comparator:代碼基本差很少,在Arrays的sort方法,因爲Compartor不爲null,根據預設好的系統參數:LegacyMergeSort.userRequested來判斷調用舊的歸併排序函數仍是調用一個更高性能的歸併排序算法TimSort,以legacyMergeSort爲入口:性能
private static <T> void legacyMergeSort(T[] a, int fromIndex, int toIndex, Comparator<? super T> c) { T[] aux = copyOfRange(a, fromIndex, toIndex); if (c==null) mergeSort(aux, a, fromIndex, toIndex, -fromIndex); else mergeSort(aux, a, fromIndex, toIndex, -fromIndex, c); } @SuppressWarnings({"rawtypes", "unchecked"}) 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++]; } }
從帶有Comparator參數的mergeSort函數可知:this
... 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; ...
調用了Comparator的compare函數來比較兩個bean類code