【问题标题】:Comparator compare() method sorting confusion比较器 compare() 方法排序混淆
【发布时间】:2015-03-17 19:28:57
【问题描述】:

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

【问题讨论】:

  • 您为什么希望compare 调用以任何特定顺序使用参数?
  • 我期望因为,我期望上升行为或下降行为。简单的单词排序,所以这就是为什么这个问题
  • 任何排序顺序都可以使用compare 参数以任何顺序完成。是否执行 a < bb > a 的等效操作并不重要。

标签: java sorting comparator comparable


【解决方案1】:
【解决方案2】:

当您实现 Comparator 时,顺序无关紧要,您只需要遵守该类协定并根据需要实现它。 您只能在知道输入和实现的情况下推断调用的顺序。

为了完整起见,从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 &lt; INSERTIONSORT_THRESHOLD,因此实际上将为这个小的 4 元素数组执行插入排序。

编辑:错误的合并排序,已修复。

【讨论】:

  • 感谢您的回答。我需要了解归并排序才能深入了解这一切。
【解决方案3】:

我不知道你为什么认为 o1 应该是 map 而 o2 应该是 pen。对此没有任何保证,实际上,您在实现compare() 方法时不应该关心它。

【讨论】:

    【解决方案4】:

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

    Arrays.sort(Object[]) 使用 Mergesort,但如果您所担心的只是获得一个排序数组,这并不重要。只要您符合 Comparator 接口 (http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html) 的要求,您的数组就会正确排序。

    【讨论】:

      猜你喜欢
      • 2020-07-04
      • 2014-12-08
      • 2012-08-18
      • 2017-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-03
      相关资源
      最近更新 更多