对于一个数组来说
如果我们想要从大到小排序一般会这么写
Integer[] nums = {1,2,3};
Arrays.sort(nums, new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
return b - a;
}
});
//lambda 表达式
Arrays.sort(nums, (a, b) -> b - a);
为什么这么写可以? 我们以 Arrays.sort 源码为例看看到底是怎么排序的。
private static void mergeSort(Object[] src,
Object[] dest,
int low, int high, int off,
Comparator c) {// c 就是我们实现的Comparator
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++];
}
}
可以看到底层用的是归并排序,我们直接看最下面几行代码。
// 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 c.compare
Arrays.sort(nums, (a, b) -> b - a);
那么分为两种情况
1.src[p] >= src[q]
那么 c.compare(src[p], src[q])
我们返回的是 src[q] - src[p]
返回的是一个小于等于0的数 也就意味着 下标 p++
也就是说谁大谁的下标后移了
也就实现了从大到小排序
2.src[p] < src[q]
同上分析
对于其他的数据结构排序也是同样的规则
标签:src,JAVA,自定义,int,mid,high,dest,源码,low From: https://www.cnblogs.com/ganyq/p/18189096