Java Comparator解析
今日はランキングのバグを修正して、その中でコンパレータComparatorを実現したことを発見して、以前もずっと使っていましたが、ただその毛皮を知っていて、今日は深く研究して、そのソースコードをひっくり返します.
まず、集合をソートするときにComparatorが実現され、私たちのニーズに応じて必要なソートが可能であることはよく知られています.
主なソートロジックはcompareによって実現される.
-1を返すと、入力パラメータの位置を切り替える必要がないことを示します.
0を返すと、値が等しいことを示し、スワップする必要もありません.
1を返すと、値をスワップする必要があることを示します.
Demoを書いて実験を行いました
結果は次のとおりです.
[1, 4, 3, 6]
o2:4-o1:1=3
o2:3-o1:1=2
o2:3-o1:4=-1
o2:6-o1:1=5
o2:6-o1:3=3
o2:6-o1:4=2
[6, 4, 3, 1]
このように見ると、ソートの内部アルゴリズムは泡のように、入って見てみましょう.
Collections.sort()もArrays.sort();
続けていく:
Arrays.sort();
正主を見ました:mergeSort();
2点挿入ソートアルゴリズムが表示されます.
では、前の推定バブルは間違っています.やはりソースコードにフォローしてみなければなりませんね.
まず、集合をソートするときにComparatorが実現され、私たちのニーズに応じて必要なソートが可能であることはよく知られています.
主なソートロジックはcompareによって実現される.
-1を返すと、入力パラメータの位置を切り替える必要がないことを示します.
0を返すと、値が等しいことを示し、スワップする必要もありません.
1を返すと、値をスワップする必要があることを示します.
Demoを書いて実験を行いました
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ComparatorTest {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(4);
list.add(3);
list.add(6);
System.out.println(list);
Collections.sort(list, comparator_int);
System.out.println(list);
}
public static Comparator<Integer> comparator_int = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
System.out.println("o2:" + o2 + "-" + "o1:" + o1 + "=" + (o2 - o1));
return o2 - o1;
}
};
}
結果は次のとおりです.
[1, 4, 3, 6]
o2:4-o1:1=3
o2:3-o1:1=2
o2:3-o1:4=-1
o2:6-o1:1=5
o2:6-o1:3=3
o2:6-o1:4=2
[6, 4, 3, 1]
このように見ると、ソートの内部アルゴリズムは泡のように、入って見てみましょう.
Collections.sort()もArrays.sort();
public static <T> void sort(List<T> list, Comparator<? super T> c) {
Object[] a = list.toArray();
Arrays.sort(a, (Comparator)c);
ListIterator i = list.listIterator();
for (int j=0; j<a.length; j++) {
i.next();
i.set(a[j]);
}
}
続けていく:
Arrays.sort();
public static <T> void sort(T[] a, Comparator<? super T> c) {
T[] aux = (T[])a.clone();
if (c==null)
mergeSort(aux, a, 0, a.length, 0);
else
mergeSort(aux, a, 0, a.length, 0, c);
}
正主を見ました:mergeSort();
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++];
}
}
2点挿入ソートアルゴリズムが表示されます.
では、前の推定バブルは間違っています.やはりソースコードにフォローしてみなければなりませんね.