zoukankan      html  css  js  c++  java
  • Comparator的compare方法如何定义升序降序

    我们都知道compare(int o1, int o2)方法 return o1 - o2 是升序,return o2 - o1 是降序。那么原因我们不妨跳进去源码看一下。

       public static <T> void sort(T[] a, Comparator<? super T> c) {
          if (c == null) {
              sort(a);
          } else {
              if (LegacyMergeSort.userRequested)
                  legacyMergeSort(a, c);
              else
                  TimSort.sort(a, 0, a.length, c, null, 0, 0);
          }
      }
    

    可以看出他是进去了else内,不妨先进入legacyMergeSort看一下

        private static <T> void legacyMergeSort(T[] a, Comparator<? super T> c) {
            T[] aux = a.clone();
            if (c==null)
                mergeSort(aux, a, 0, a.length, 0);
            else
                mergeSort(aux, a, 0, a.length, 0, c);
        }
    

    这里很明显也是进去了else内,继续看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++];
            }
        }
    

    这一段的代码关键就是如下部分

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

    可以看到这里面调用了compare方法,当方法的返回值大于0的时候就将数组的前一个数和后一个数做交换。以升序为例来讲解,升序的话compare方法就 return o1 - o2,那么就是 return dest[j-1] - dest[j]。
    也就是说,compare的参数a,b是序列相邻的两个元素,compare定义了什么时候交换这2个元素值,当返回值大于0时交换,小于等于0时不做操作。

    参考
    [1]:Comparator的compare方法如何定义升序降序

  • 相关阅读:
    性能测试之开源的性能监控软件
    POJ 2553 The Bottom of a Graph TarJan算法题解
    Spring AOP切面
    [2014.5.22][UBUNTU]Ubuntu与Windows系统时间不同步的问题
    MySQL bug:server-id默认被自己主动置为1
    [Android]Fragment源代码分析(二) 状态
    window nginx 启动无提示错误,却没有listen 80port
    Shell 命令--文件创建、搜索命令--总结自《Linux Shell 脚本攻略》
    freemarker 自己定义指令
    javascript Deferred和递归次数限制
  • 原文地址:https://www.cnblogs.com/Frank-Hong/p/14648853.html
Copyright © 2011-2022 走看看