美文网首页
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