1.概念
java.util.Collections 是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全等操作。 然后还有混排(Shuffling)、反转(Reverse)、替换所有的元素(fill)、拷贝(copy)、返回Collections中最小元素(min)、返回Collections中最大元素(max)、返回指定源列表中最后一次出现指定目标列表的起始位置( lastIndexOfSubList )、返回指定源列表中第一次出现指定目标列表的起始位(IndexOfSubList )、根据指定的距离循环移动指定列表中的元素(Rotate);
事实上Collections.sort方法底层就是调用的Arrays.sort方法
//Collections.sort方法
public static <T extends Comparable<? super T>> void sort(List<T> var0) {
var0.sort((Comparator)null);
}
//var0.sort
public void sort(Comparator<? super E> var1) {
int var2 = this.modCount;
//Collections.sort方法底层调用的就是Arrays.sort方法
Arrays.sort((Object[])this.elementData, 0, this.size, var1);
if (this.modCount != var2) {
throw new ConcurrentModificationException();
} else {
++this.modCount;
}
}
再来看看Arrays.sort方法
public static <T> void sort(T[] var0, int var1, int var2, Comparator<? super T> var3) {
if (var3 == null) {//没有设置比较规则走这里
sort(var0, var1, var2);//sort的实现请看下面的代码块
} else {//设置了比较规则走这里
rangeCheck(var0.length, var1, var2);
//legacyMergeSort归并排序, 默认是不使用这个方法
if (Arrays.LegacyMergeSort.userRequested) {
legacyMergeSort(var0, var1, var2, var3);
} else {//所以使用的是TimSort.sort
//TimSort是mergeSort的一种改进
TimSort.sort(var0, var1, var2, var3, (Object[])null, 0, 0);
}
}
}
sort
public static void sort(Object[] var0, int var1, int var2) {
rangeCheck(var0.length, var1, var2);
if (Arrays.LegacyMergeSort.userRequested) {
legacyMergeSort(var0, var1, var2);
} else {
ComparableTimSort.sort(var0, var1, var2, (Object[])null, 0, 0);
}
}
2.函数解释
1.TimSort.sort与ComparableTimSort.sort基本相同, 唯一区别的是后者需要对象是Comparable可比较的,不需要特定Comparator,而前者利用提供的Comparator进行排序
2.TimSort是mergeSort的一种改进, Timsort 排序是结合了归并排序(merge sort)和插入排序(insertion sort)而得出的排序算法
步骤如下:
0、数组长度小于某个值,直接用二分插入排序算法, 否则执行下面的步骤
1、根据数组长度计算minrun(最小run(分区)长度)
2、将数组按升序或者严格降序(需反转为升序)分割成一个一个run(分区),长度小于minrun的分区则使用插入排序进行扩充
3、将分区的首元素下标及长度放入栈中,当栈顶run的长度满足 runLen[n-2] + runLen[n-1] >= runLen[n-3]
或者满足runLen[n-1] >= runLen[n-2]时(n表示栈中run的个数,下标n-1就是栈顶),使用归并排序将栈顶相邻
最短的两个run进行合并,继续对剩余的数组元素进行分区。
4、数组分区完成后将栈中剩余的run全部合并。
//TimSort.sort(var0, var1, var2, var3, (Object[])null, 0, 0);
static void sort(Object[] var0, int var1, int var2, Object[] var3, int var4, int var5) {
assert var0 != null && var1 >= 0 && var1 <= var2 && var2 <= var0.length;
int var6 = var2 - var1;
if (var6 >= 2) {
if (var6 < 32) {//数组元素数量<32用二分插入排序
int var11 = countRunAndMakeAscending(var0, var1, var2);
binarySort(var0, var1, var2, var1 + var11);
} else {
ComparableTimSort var7 = new ComparableTimSort(var0, var3, var4, var5);
int var8 = minRunLength(var6);
do {
int var9 = countRunAndMakeAscending(var0, var1, var2);
if (var9 < var8) {//长度小于minrun的分区则使用插入排序进行扩充
int var10 = var6 <= var8 ? var6 : var8;
binarySort(var0, var1, var1 + var10, var1 + var9);
var9 = var10;
}
var7.pushRun(var1, var9);
var7.mergeCollapse();
var1 += var9;
var6 -= var9;
} while(var6 != 0);
assert var1 == var2;
var7.mergeForceCollapse();
assert var7.stackSize == 1;
}
}
}