對於一個陣列來說
如果我們想要從大到小排序一般會這麼寫
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]
同上分析
對於其他的資料結構排序也是同樣的規則