JDK1.8 source code interpretation of Comparator

Foreword

  • Comparison function is applied to the total-ordered collection of certain objects.
  • Comparator may be passed to the sorting method (e.g. {@link Collections # sort (List, Comparator) Collections.sort}
  • Or {@link Arrays # sort (Object [], Comparator) Arrays.sort}), the sort order to precisely control.
  • Further comparator may sequentially certain data structures (e.g., set ordering {@link SortedSet} or {@link SortedMap FIG sort}) for controlling,
  • Provided that there is no set or ordering {@ link object than natural ordering}.
  • S for each of e1 and e2, and only when equal c.compare (e1, e2) == 0 Boolean value e1.equals (e2) Boolean value,
  • C fishes sort comparator element S is applied is referred to equal equals.
  • When used can be applied with equal sorted set (or sorted map) is equal to the sort comparator inconsistent, caution should be exercised.
  • It is assumed that sort with explicit comparator c set (or map sort) with the elements (or keys) extracted from the set S.
  • If the sort of S in equation c applied inconsistent, the sorted set (or sorted map) will exhibit "strange."
  • In particular, the sorted set (or sorted map) would violate the set (or Map) general contract, which is defined eauals.
  • For example, there are two elements {@code a} and {@code b}, such that {@code (a.equals (b) && c.compare (a, b)! = 0)}
  • These two elements are added to the empty TreeSet with comparator.
  • {@Code add} The second operation returns true (and will increase the size of the tree set),
  • Because from the point of view of the tree set, {@ code a} and {@code b} are not equal, even though it does not meet {@link Set # add Set.add} method specification.
  • Note: Comparator usually have to implement java.io.Serializable, it's a good idea,
  • Since they may be used as a sequence of data structures (e.g., {@link TreeSet}, {@ link TreeMap}) sorting method.
  • In order to successfully serialized data structure, the comparator (if provided) must implement Serializable.

Source



package java.util;
@FunctionalInterface
public interface Comparator<T> {
    /**
     * 第一个参数大于第二个参数,返回正
     * 第一个参数等于第二个参数,返回0
     * 第一个参数小于第二个参数,返回负
     *
     * 实现者必须确保所有x和y的sgn(compare(x,y))== -sgn(compare(y,x))。
     * (这意味着,当且仅当compare(y,x)引发异常时,compare(x,y)才必须引发异常。)
     *
     * 实现者还必须确保该关系是可传递的:(((compare(x,y)> 0)&&(compare(y,z)> 0))意味着compare(x,z)> 0。
     *
     * 最后,实现者必须确保compare(x,y)== 0意味着所有z的sgn(compare(x,z))== sgn(compare(y,z))。
     *
     * 通常是这种情况,但并非严格要求(compare(x,y)== 0)==(x.equals(y))。
     * 一般而言,任何违反此条件的比较器都应明确指出这一事实。
     * 推荐的语言是“注意:此比较器强加与等号不一致的顺序”。
     */
    int compare(T o1, T o2);

    /**
     * 指示其他某个对象是否“等于”该比较器。此方法必须遵守{@link Object#equals(Object)}的一般约定。
     * 此外,仅当指定对象也是一个比较器并且施加与该比较器相同的顺序时,此方法才能返回true。
     * 因此,comp1.equals(comp2)表示每个对象引用o1和o2的sgn(comp1.compare(o1,o2))== sgn(comp2.compare(o1,o2))。
     *
     * 请注意,始终不覆盖Object.equals(Object)始终是安全的。
     * 但是,在某些情况下,重写此方法可以通过允许程序确定两个不同的比较器施加相同的顺序来提高性能。
     */
    boolean equals(Object obj);

    /**
     * 返回强加此比较器相反顺序的比较器。
     */
    default Comparator<T> reversed() {
        return Collections.reverseOrder(this);
    }

    /**
     * 返回带有另一个比较器的字典顺序比较器。
     * 如果此{@code Comparator}认为两个元素相等,即{@code compare(a,b)== 0},则使用{@code other}确定顺序。
     * 如果指定的比较器也可序列化,则返回的比较器可序列化。
     * 例如,要根据长度对{@code String}的集合进行排序,然后对不区分大小写的自然顺序进行排序,可以使用以下代码来组成比较器,
     */
    default Comparator<T> thenComparing(Comparator<? super T> other) {
        Objects.requireNonNull(other);
        return (Comparator<T> & Serializable) (c1, c2) -> {
            int res = compare(c1, c2);
            return (res != 0) ? res : other.compare(c1, c2);
        };
    }

    /**
     * 返回按字典顺序排序的比较器,该比较器的功能是提取要与给定的{@code Comparator}进行比较的键。
     */
    default <U> Comparator<T> thenComparing(
            Function<? super T, ? extends U> keyExtractor,
            Comparator<? super U> keyComparator)
    {
        return thenComparing(comparing(keyExtractor, keyComparator));
    }

    /**
     * 返回具有按字典顺序排序的比较器,该函数具有提取{@code Comparable}排序键的功能。
     */
    default <U extends Comparable<? super U>> Comparator<T> thenComparing(
            Function<? super T, ? extends U> keyExtractor)
    {
        return thenComparing(comparing(keyExtractor));
    }

    /**
     * 返回具有按字典顺序排序的比较器,该函数具有提取{@code int}排序键的功能。
     */
    default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) {
        return thenComparing(comparingInt(keyExtractor));
    }

    /**
     * 返回具有按字典顺序排序的比较器,该函数具有提取{@code long}排序键的功能。
     */
    default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor) {
        return thenComparing(comparingLong(keyExtractor));
    }

    /**
     * 返回具有按字典顺序排序的比较器,该函数具有提取{@code double}排序键的功能。
     */
    default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) {
        return thenComparing(comparingDouble(keyExtractor));
    }

    /**
     * 返回一个强加自然顺序相反的比较器。
     * 返回的比较器是可序列化的,并且在比较{@code null}时抛出{@link NullPointerException}。
     */
    public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
        return Collections.reverseOrder();
    }

    /**
     * 返回一个比较器,该比较器以自然顺序比较{@link Comparable}对象。
     * 返回的比较器是可序列化的,并且在比较{@code null}时抛出{@link NullPointerException}。
     */
    @SuppressWarnings("unchecked")
    public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
        return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
    }

    /**
     * 返回一个友好友好的比较器,该比较器认为{@code null}小于非null。
     * 如果两者均为{@code null},则认为它们相等。如果两者都不为空,则使用指定的{@code Comparator}来确定顺序。
     * 如果指定的比较器为{@code null},则返回的比较器将所有非null值视为相等。如果指定的比较器可序列化,则返回的比较器可序列化。
     */
    public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) {
        return new Comparators.NullComparator<>(true, comparator);
    }

    /**
     * 返回一个友好友好的比较器,该比较器认为{@code null}大于非null。
     * 如果两者均为{@code null},则认为它们相等。如果两者都不为空,则使用指定的{@code Comparator}来确定顺序。
     * 如果指定的比较器为{@code null},则返回的比较器将所有非null值视为相等。如果指定的比较器可序列化,则返回的比较器可序列化。
     */
    public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) {
        return new Comparators.NullComparator<>(false, comparator);
    }

    /**
     * 接受一个函数,该函数从类型{@code T}中提取排序键,然后返回一个{@code Comparator},
     * 使用指定的{@link Comparator}通过该排序键进行比较。如果指定的函数和比较器均可序列化,则返回的比较器可序列化。
     */
    public static <T, U> Comparator<T> comparing(
            Function<? super T, ? extends U> keyExtractor,
            Comparator<? super U> keyComparator)
    {
        Objects.requireNonNull(keyExtractor);
        Objects.requireNonNull(keyComparator);
        return (Comparator<T> & Serializable)
            (c1, c2) -> keyComparator.compare(keyExtractor.apply(c1),
                                              keyExtractor.apply(c2));
    }

    /**
     * 接受一个函数,该函数从类型{@code T}中提取一个{@link java.lang.Comparable Comparable}排序键,
     * 并返回一个按该排序键进行比较的{@code Comparator}。如果指定的函数也可序列化,则返回的比较器可序列化。
     */
    public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
            Function<? super T, ? extends U> keyExtractor)
    {
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
    }

    /**
     * 接受一个函数,该函数从类型{@code T}中提取一个{@code int}排序键,并返回一个与该排序键进行比较的{@code Comparator}。
     * 如果指定的函数也可序列化,则返回的比较器可序列化。
     */
    public static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) {
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
    }

    /**
     * 接受一个函数,该函数从类型{@code T}中提取一个{@code long}排序键,并返回一个与该排序键进行比较的{@code Comparator <T>}。
     * 如果指定的函数也可序列化,则返回的比较器可序列化。
     */
    public static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor) {
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2));
    }

    /**
     * 接受一个函数,该函数从类型{@code T}中提取一个{@code double}排序键,并返回一个{@code Comparator},并通过该排序键进行比较。
     * 如果指定的函数也可序列化,则返回的比较器可序列化。 
     */
    public static<T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor) {
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));
    }
}

复制代码

Guess you like

Origin juejin.im/post/5e8e3782e51d4546f03d90b3