Collections類提供了兩個sort方法,目標都是List<T> list,不一樣時可選擇本身指定一個Comparator。java
public static <T> void sort(List<T> list, Comparator<? super T> c) { list.sort(c); } public static <T extends Comparable<? super T>> void sort(List<T> list) { list.sort(null); }
調用的都是list的sort,以下:算法
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:this
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); } }
期三行調用的sort:spa
public static void sort(Object[] a) { if (LegacyMergeSort.userRequested) legacyMergeSort(a); else ComparableTimSort.sort(a, 0, a.length, null, 0, 0); }
具體的排序細節就不展現了,最後兩個片斷能夠看出。Array提供了兩種排序算法,MergeSort和TimSort。默認用的是Java7新提供的TimSort,經過在啓動參數中指定-Djava.util.Arrays.useLegacyMergeSort=true能夠用原來的MergeSort。這裏的TimSort很多人被一個細節坑過,異常以下:對象
Exception in thread "main" java.lang.IllegalArgumentException: Comparison
method violates its general contract!排序
緣由是,使用TimSort時,對象間的對比較更加嚴格,當指定compare時,必須保證如下三點:get
public int compare(Test o1, Test o2) { return o1.getValue() > o2.getValue() ? 1 : -1; }
乍一看沒什麼毛病,可是對比上面的條件a,就會發現不知足了,那就是:當o1的value與o2的value相等時!it
解決方法:io
public int compare(Test o1, Test o2) { return o1.getValue() == o2.getValue() ? 0 : (o1.getValue() > o2.getValue() ? 1 : -1); }