java解惑65:疑似排序的惊人传奇

观察一段程序

import java.util.*;
public class Sixtyfifth{
        public static void main(String[] arts){
                Random rand = new Random();
                Integer[] arr = new Integer[100];
                for(int i = 0 ; i < arr.length ; i ++){
                        arr[i] = rand.nextInt();
                }
                Comparator<Integer> cmp = new Comparator<Integer>(){
                        public int compare(Integer i1 , Integer i2){
                                return i2 - i1;
                                //return (i2 < i1 ? -1: (i2 > i1 ? 1 : 0));
                        }
                };
                Arrays.sort(arr,cmp);
                System.out.println(order(arr));
        }
        enum Order{ASCENDING,DESCENDING,CONSTANT,UNORDERED};
        static Order order(Integer[] a){
                boolean ascending = false;
                boolean descending = false;
                for(int i = 1 ; i < a.length ; i ++){
                        ascending |= (a[i] > a[i-1]);
                        descending |= (a[i] < a[i - 1]);
                }
                if(ascending && !descending)
                        return Order.ASCENDING;
                if(!ascending && descending)
                        return Order.DESCENDING;
                if(!ascending)
                        return Order.CONSTANT;
                return Order.UNORDERED;
        }
}                                                                                                                                                             
将打印出什么?
是DESCENDING吗?

运行发现是:UNORDERED

先把好奇心放放!观察下面的程序

public class Overflow{
     public static void main(String[] args){
            int x = -2000000000;
            int z = 2000000000;
            System.out.println(x - z);
     }
}
打印出什么了?是:294967296!!!

不是应该是负数吗?是,理论上是负数,但是在计算机界,却是正数,理由是溢出!!!

由上述代码可知,负数减正数也可能得到正数!

OK,现在来考虑第一段代码中的比较器cmp,可以发现这个比较器并不是每次都能得到正确的结果,比如,i1=2000000000,i2=-2000000000,用这个比较器的结果就是i2>i1,显然结果是错误的。

综上所述,可以知道比较器有时候并不能简单的用减法来比较大小!!!

改正:

return i2 - i1;
改正为:

return (i2 < i1 ? -1: (i2 > i1 ? 1 : 0));
如此比较器就可以正常使用了。

此题还需要注意:

使用Arrays.sort(array,comparator)时array的类型T1需要是comparator的类型的父类型。

观察下函数的原型(来自api):

static
<T> void
sort(T[] a,Comparator<? super T> c)
          根据指定比较器产生的顺序对指定对象数组进行排序。

你可能感兴趣的:(java,comparator,Java解惑,疑似排序的排序)