java Comparator接口中compare方法决定排序的升序降序问题

taxueq 2016-11-12 09:39:42
public class Sort implements Comparator<Integer>{
public static void main(String[] args) {
Integer[] a={3,5,1,4,0,8};
Arrays.sort(a, new Sort());
for (Integer integer : a) {
System.out.print(integer.intValue()+" ");
}
}
@Override
public int compare(Integer arg0, Integer arg1) {
System.out.println("arg0:"+arg0.intValue()+" arg1:"+arg1.intValue());
//return arg0-arg1;
return arg1-arg0;
}
}
compare方法中为什么return arg0-arg1就是升序排序,return arg1-arg0就是降序排序?
求大神告知!!!
...全文
16885 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
u011019786 2017-09-12
  • 打赏
  • 举报
回复
用的是TimSort.sort 答案是错的
JF44262066 2017-09-05
  • 打赏
  • 举报
回复
引用 5 楼 jstxzhangrui 的回复:
[quote=引用 2 楼 taxueq 的回复:] [quote=引用 1 楼 jstxzhangrui 的回复:] int compare(T o1,T o2) Returns: a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second. 我给你翻译一下: 第一次参数比第二个参数小返回负整数,等于返回0大于返回正整数。 return arg0-arg1和return arg1-arg0不就是差个负号么。当return arg0-arg1告诉你arg0大于arg1时,return arg1-arg0不就是告诉你 arg1大于arg0么,所以排序正好颠倒
我是想知道compare方法中为什么return arg0-arg1就决定是升序排序,return arg1-arg0就决定是降序排序的本质,为什么return arg0-arg1就不能是降序排序,return arg1-arg0就不能是升序排序? 首先感谢你回复,但好像并没告诉我原因[/quote] 不好意思,白天比较忙,很少逛论坛。然后想说你这种精神很像我当初刚学java时一样,这是好事,说明你肯钻研,不过java的API实在众多,如果你每个都深究的,很难学好的,对于API那都是优秀设计者设计好的,你需要掌握得是如何使用。 言归正传,下面给你解释下原因,这就得从java源码入手了。 首先,这是你调用的sort方法
    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中的if,那么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++];
        }
    }
这段代码就比较长了,重点来了
   for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)
                    swap(dest, j, j-1);
这个看到了么,如果调用compare方法大于0,就把前一个数和后一个数交换,也就是把大的数放后面了,即所谓的升序了。那么再想想看return arg0-arg1是不是返回的与这里正好匹配呢。差不多说这么多,相信你应该明白了。[/quote] 非常感谢这段源码, 我通过他的规则猜到了是大于零就交换,不过我在很多地方见过排序的例子返回了三个状态,分别是1、0、-1,我不清楚为什么还需要返回-1 所以才来搜
taxueq 2016-11-14
  • 打赏
  • 举报
回复
引用 5 楼 jstxzhangrui 的回复:
[quote=引用 2 楼 taxueq 的回复:] [quote=引用 1 楼 jstxzhangrui 的回复:] int compare(T o1,T o2) Returns: a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second. 我给你翻译一下: 第一次参数比第二个参数小返回负整数,等于返回0大于返回正整数。 return arg0-arg1和return arg1-arg0不就是差个负号么。当return arg0-arg1告诉你arg0大于arg1时,return arg1-arg0不就是告诉你 arg1大于arg0么,所以排序正好颠倒
我是想知道compare方法中为什么return arg0-arg1就决定是升序排序,return arg1-arg0就决定是降序排序的本质,为什么return arg0-arg1就不能是降序排序,return arg1-arg0就不能是升序排序? 首先感谢你回复,但好像并没告诉我原因[/quote] 不好意思,白天比较忙,很少逛论坛。然后想说你这种精神很像我当初刚学java时一样,这是好事,说明你肯钻研,不过java的API实在众多,如果你每个都深究的,很难学好的,对于API那都是优秀设计者设计好的,你需要掌握得是如何使用。 言归正传,下面给你解释下原因,这就得从java源码入手了。 首先,这是你调用的sort方法
    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中的if,那么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++];
        }
    }
这段代码就比较长了,重点来了
   for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)
                    swap(dest, j, j-1);
这个看到了么,如果调用compare方法大于0,就把前一个数和后一个数交换,也就是把大的数放后面了,即所谓的升序了。那么再想想看return arg0-arg1是不是返回的与这里正好匹配呢。差不多说这么多,相信你应该明白了。[/quote] 谢谢啊,指明关键点了
shinerio 2016-11-13
  • 打赏
  • 举报
回复
引用 2 楼 taxueq 的回复:
[quote=引用 1 楼 jstxzhangrui 的回复:] int compare(T o1,T o2) Returns: a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second. 我给你翻译一下: 第一次参数比第二个参数小返回负整数,等于返回0大于返回正整数。 return arg0-arg1和return arg1-arg0不就是差个负号么。当return arg0-arg1告诉你arg0大于arg1时,return arg1-arg0不就是告诉你 arg1大于arg0么,所以排序正好颠倒
我是想知道compare方法中为什么return arg0-arg1就决定是升序排序,return arg1-arg0就决定是降序排序的本质,为什么return arg0-arg1就不能是降序排序,return arg1-arg0就不能是升序排序? 首先感谢你回复,但好像并没告诉我原因[/quote] 不好意思,白天比较忙,很少逛论坛。然后想说你这种精神很像我当初刚学java时一样,这是好事,说明你肯钻研,不过java的API实在众多,如果你每个都深究的,很难学好的,对于API那都是优秀设计者设计好的,你需要掌握得是如何使用。 言归正传,下面给你解释下原因,这就得从java源码入手了。 首先,这是你调用的sort方法
    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中的if,那么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++];
        }
    }
这段代码就比较长了,重点来了
   for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)
                    swap(dest, j, j-1);
这个看到了么,如果调用compare方法大于0,就把前一个数和后一个数交换,也就是把大的数放后面了,即所谓的升序了。那么再想想看return arg0-arg1是不是返回的与这里正好匹配呢。差不多说这么多,相信你应该明白了。
taxueq 2016-11-13
  • 打赏
  • 举报
回复
引用 1 楼 jstxzhangrui 的回复:
int compare(T o1,T o2) Returns: a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second. 我给你翻译一下: 第一次参数比第二个参数小返回负整数,等于返回0大于返回正整数。 return arg0-arg1和return arg1-arg0不就是差个负号么。当return arg0-arg1告诉你arg0大于arg1时,return arg1-arg0不就是告诉你 arg1大于arg0么,所以排序正好颠倒
我是想知道compare方法中为什么return arg0-arg1就决定是升序排序,return arg1-arg0就决定是降序排序的本质,为什么return arg0-arg1就不能是降序排序,return arg1-arg0就不能是升序排序? 首先感谢你回复,但好像并没告诉我原因
解开者 2016-11-13
  • 打赏
  • 举报
回复
小于0就是左边小,大于0就是右边小。 因为接口定义和集合框架对该接口方法的调用都在jdk里,所以这个规则属于jdk的内部协定,它也完全可以设计成反过来的。按现状设计,是为了更符合人类的认知。
「已注销」 2016-11-13
  • 打赏
  • 举报
回复
API中的方法说明,定义吧 你非要问为什么就去问JAVA为什么是JAVA
shinerio 2016-11-12
  • 打赏
  • 举报
回复
int compare(T o1,T o2) Returns: a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second. 我给你翻译一下: 第一次参数比第二个参数小返回负整数,等于返回0大于返回正整数。 return arg0-arg1和return arg1-arg0不就是差个负号么。当return arg0-arg1告诉你arg0大于arg1时,return arg1-arg0不就是告诉你 arg1大于arg0么,所以排序正好颠倒

62,625

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧