比较器compare()方法排序混乱

时间:2015-03-17 19:28:57

标签: java sorting comparator comparable

我正在从Kathy和Seirra的书中做自测问题。其中一个问题出了问题,所以我在IDE中尝试。我的困惑可以从这张图片中找到。主要问题是当我调试它时,我在比较方法中放了一个调试点。如果工具提示可以被注意到o1持有值笔。我以为o1应该是map,而o2应该是pen。有人能解释我这种困惑吗?

Comparator Confusion

4 个答案:

答案 0 :(得分:1)

答案 1 :(得分:1)

当您实施Comparator时,顺序无关紧要,您只需要符合该Class类合同并根据需要实现它。 您只能在知道输入和实现的情况下推断出调用的顺序。

仅仅为了完整起见,从OpenJDK 7开始,这是使用合并排序的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);
}

Arrays::mergeSort

private static final int INSERTIONSORT_THRESHOLD = 7;

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++];
    }
}

在您的示例中,这是真的:length < INSERTIONSORT_THRESHOLD因此将对此小4元素数组实际执行插入排序。

编辑:错误的mergeSort,已修复。

答案 2 :(得分:0)

我不知道你为什么期望o1应该是map而o2应该是pen。我们无法保证这一点,事实上,在实施compare()方法时,您不应该关心它。

答案 3 :(得分:0)

问题是怎么出错的?最初的问题是什么?

Arrays.sort(Object [])使用Mergesort,但如果你担心的是得到一个排序的数组,那真的不重要。只要您符合Comparator界面(http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html)的要求,您的阵列就会正确排序。