美文网首页
Comparable/Comparator分析

Comparable/Comparator分析

作者: 言西枣 | 来源:发表于2016-05-18 20:01 被阅读234次

    源码来自jdk1.8


    TreeMap, TreeSet, PriorityQueue等天生有序的数据结构,或是Arrays, Collections方法类的排序函数等中,需要对集合元素进行比较,如果不是String或是基本类型等平台自带的类型,就需要自己实现比较元素的方法。

    对于Collections来说:

    public static <T extends Comparable<? super T>> void sort(List<T> list) {
            list.sort(null);
        }
    

    要么是list中的类型原本就实现了Comparable接口

    public static <T> void sort(List<T> list, Comparator<? super T> c) {
            list.sort(c);
        }
    

    要么是在调用sort的时候提供了这个类型的比较器(实现Comparator接口)

    对于Arrays来说:

    与Collections也是一样的,提供一个Comparator或者实现Comparable

    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);
            }
        }
    
     /**
         * Sorts the specified array of objects into ascending order, according
         * to the {@linkplain Comparable natural ordering} of its elements.
         * All elements in the array must implement the {@link Comparable}
         * interface.  Furthermore, all elements in the array must be
         * <i>mutually comparable</i> (that is, {@code e1.compareTo(e2)} must
         * not throw a {@code ClassCastException} for any elements {@code e1}
         * and {@code e2} in the array).
         *
         * @param a the array to be sorted
         * @throws ClassCastException if the array contains elements that are not
         *         <i>mutually comparable</i> (for example, strings and integers)
         * @throws IllegalArgumentException (optional) if the natural
         *         ordering of the array elements is found to violate the
         *         {@link Comparable} contract
         */
        public static void sort(Object[] a) {
            if (LegacyMergeSort.userRequested)
                legacyMergeSort(a);
            else
                ComparableTimSort.sort(a, 0, a.length, null, 0, 0);
        }
    

    对TreeSet,TreeMap,PriorityQueue来说:

    如果元素类型没有实现Comparable接口,那么在使用的过程中,如add一个元素就会抛出如下异常:

     Exception in thread "main" java.lang.ClassCastException: Collection.User cannot be cast to java.lang.Comparable
        at java.util.TreeMap.compare(TreeMap.java:1290)
        at java.util.TreeMap.put(TreeMap.java:538)
        at java.util.TreeSet.add(TreeSet.java:255)
    

    同样的,也可以在创建TreeMap等数据类型的时候传入一个元素类型的Comparator
    由于需要进行比较,所以这些数据结构不允许null值。

    什么是Mutually Comparable

    为了A类和B类能够互相比较,必须满足如下要求:

    • 对A类的一个对象调用compareTo时传入一个B类的对象(包括子类对象)必须是允许的,也就是不会抛出ClassCastException
    • 对B类的一个对象调用compareTo时传入一个A类的对象(包括子类对象)必须是允许的,也就是不会抛出ClassCastException
    • 如果a.compareTo(b)返回x,那么b.compareTo(a)必须返回一个相反符号的y,如果x==0,那么y==0

    Comparable<T>

    public interface Comparable<T> {
        /**
         * Compares this object with the specified object for order.  Returns a
         * negative integer, zero, or a positive integer as this object is less
         * than, equal to, or greater than the specified object.
         */
        public int compareTo(T o);
    }
    

    Comparator<T>

    Comparator<T>接口中给出了很多方法,但除了最核心的compare以外,都给出了默认的实现,所以在使用Comparator时,也只需要实现compare一个方法就可以了:

    public interface Comparator<T> {
        /**
         * Compares its two arguments for order.  Returns a negative integer,
         * zero, or a positive integer as the first argument is less than, equal
         * to, or greater than the second.<p>
         * 
         * @param o1 the first object to be compared.
         * @param o2 the second object to be compared.
         * @return a negative integer, zero, or a positive integer as the
         *         first argument is less than, equal to, or greater than the
         *         second.
         * @throws NullPointerException if an argument is null and this
         *         comparator does not permit null arguments
         * @throws ClassCastException if the arguments' types prevent them from
         *         being compared by this comparator.
         */
        int compare(T o1, T o2);
        // 省略了其他方法
    }
    

    Comparator vs Comparable

    java.lang.Comparable 用来确定一个类的对象的自然顺序(natural ordering), 然而你可以根据自己的需要使用java.util.Comparator 来确定任何的对象顺序。
    你只能通过Comparable确定一个固定的对象顺序,使用Comparator却可以实现任意多个自定义顺序。

    Readmore: http://java67.blogspot.com/2013/08/difference-between-comparator-and-comparable-in-java-interface-sorting.html#ixzz490WANROH

    相关文章

      网友评论

          本文标题:Comparable/Comparator分析

          本文链接:https://www.haomeiwen.com/subject/xujwrttx.html