Java Comparator 解析
今日修一排序的bug,发现其中是实现了比较器Comparator,之前也是一直在用,但是只是知其皮毛,今天便深究一下,翻其源码。
首先,大家都知道对于集合进行排序的时候,可以实现Comparator,则可以按我们的需求进行所需的排序。
主要的排序逻辑则是由compare来实现。
当返回-1时,表明不需要对传入参数的位置进行调换;
返回0时,表明值相等,也不需要进行调换。
返回1时,表明需要对值进行调换。
遂写一Demo进行了实验:
Java代码:
- 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();
Java代码:
- 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();
Java代码:
- 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();
Java代码:
- 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++];
- }
- }
可以看到时用了二分插入排序算法。
那么之前的估测冒泡是错的,看来还是要跟进源码去看才知道呀!
原文参考自站长网:http://www.software8.co/wzjs/java/3496.html