Comparator接口源码理解

35 篇文章 0 订阅
34 篇文章 0 订阅
本文详细介绍了Java中的Comparator接口,包括其作用、概述、源码分析以及主要方法如compare、equals、reversed、thenComparing等的解释,还提到了与Comparable接口的区别和使用场景。
摘要由CSDN通过智能技术生成


前言

本文章帮助大家对Comparator接口的理解。


一、概述

Comparator意为比较器。顾名思义,它可以定义、比较对象的大小。

它不属于被比较对象的方法,是类外部的比较功能,同样有比较功能的有Comparable(可比较的)接口,但后者是从类内部提供的功能。参考Comparable接口。例如它可以作为排序的比较参数。

它是一个函数式接口,它可作为一个两个参数的有整型结果lambda表达式的接口类型。

二、源码理解

package java.util;
import java.util.Comparator;

使用Comparator接口时,需引入此包。

Comparator接口

public interface Comparator<T> { /*...*/ }

使用接口时传入泛型T,为要比较对象的元素的类型。

注意:建议其实现类实现Serializable可序列化接口,为使诸如树等结构数据反序列化后仍能维护其功能(需要对应比较器),其比较器也应实现Serializable接口。参考Serializable

Comparator方法

compare

int compare(T o1, T o2);

比较o1o2,若o1小于o2,返回负数;若o1等于o2,返回0;若o1大于o2,返回正数,即提供函数逻辑。若参数为空但比较器不允许为空,抛出NullPointerException异常;若因参数的类型而不能比较,抛出ClassCastException异常。

注意:比较需要有“相反性”(a ≥ b ⇔ \Leftrightarrow b ≤ a)、“传递性”(a ≥ b ≥ c ⇒ \Rightarrow a ≥ c)等。

强烈建议compare(x, y)==0x.equals(y)保持一致,若不一致,请标明它们不一致。参考Object.equals方法。

equals

boolean equals(Object obj);

重写Object类的boolean equals(Object obj)方法,参考Object.equals方法。

判断此对象与obj是否相同(逻辑相同)。可以不重写,但是重写的好处就是可以判断两个(比较器)对象的比较逻辑是一样的。

reversed

default Comparator<T> reversed() { return Collections.reverseOrder(this); }

返回一个与此比较器比较逻辑相反的比较器,有compare(o1, o2) == reversed().compare(o2, o1)。参考Collections.reverseOrder方法。default关键字给出默认实现。

thenComparing

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);
    };
}

组合此比较器和other比较器的比较逻辑(且实现Serializable接口),返回比较器逻辑为:若此比较器结果相等,则进行other比较。例如组合“年份比较器”和“月份比较器”来比较两个年月的大小。若other为空,则抛出NullPointerException异常,参考Objects.requireNonNull方法。default关键字给出默认实现。

注意:若此比较器结果不相等,则other比较器不执行。若此比较器出现异常,则other比较器不执行。若返回比较器中出现异常,那么这些异常会交给返回比较器的调用方处理。

default <U> Comparator<T> thenComparing(
        Function<? super T, ? extends U> keyExtractor,
        Comparator<? super U> keyComparator)
{
    return thenComparing(comparing(keyExtractor, keyComparator));
}

传入泛型U,为比较的参数经过keyExtractor函数式计算的结果的类型。组合此比较器和原参数经过keyExtractor函数式计算的keyComparator比较器的比较逻辑。类似Comparator<T> thenComparing(Comparator<? super T> other)方法,不同的是,keyComparator比较的是原参数经过keyExtractor函数式计算的值。default关键字给出默认实现。

default <U extends Comparable<? super U>> Comparator<T> thenComparing(
        Function<? super T, ? extends U> keyExtractor)
{
    return thenComparing(comparing(keyExtractor));
}

传入泛型UU继承Comparable<? super U>接口,为比较的参数经过keyExtractor函数式计算的结果的类型,需要是可比较的(即自身带有Comparable.compareTo方法),参考Comparable接口。组合此比较器和原参数经过keyExtractor函数式计算的自然序比较逻辑。类似Comparator<T> thenComparing(Comparator<? super T> other)方法,不同的是,第二个比较的是原参数经过keyExtractor函数式计算的值。default关键字给出默认实现。

thenComparingInt

default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) {
    return thenComparing(comparingInt(keyExtractor));
}

组合此比较器和原参数经过keyExtractor函数式计算的自然序比较逻辑。类似<U extends Comparable<? super U>> Comparator<T> thenComparing(Function<? super T, ? extends U> keyExtractor)方法,不同的是,keyExtractor函数式为整型“特例化”的函数式。参考ToIntFunction接口。default关键字给出默认实现。

thenComparingLong

default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor) {
    return thenComparing(comparingLong(keyExtractor));
}

组合此比较器和原参数经过keyExtractor函数式计算的自然序比较逻辑。类似<U extends Comparable<? super U>> Comparator<T> thenComparing(Function<? super T, ? extends U> keyExtractor)方法,不同的是,keyExtractor函数式为长整型“特例化”的函数式。参考ToLongFunction接口。default关键字给出默认实现。

thenComparingDouble

default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) {
    return thenComparing(comparingDouble(keyExtractor));
}

组合此比较器和原参数经过keyExtractor函数式计算的自然序比较逻辑。类似<U extends Comparable<? super U>> Comparator<T> thenComparing(Function<? super T, ? extends U> keyExtractor)方法,不同的是,keyExtractor函数式为双精度浮点型“特例化”的函数式。参考ToDoubleFunction接口。default关键字给出默认实现。

reverseOrder

public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() { return Collections.reverseOrder(); }

静态方法,传入泛型TT继承Comparable<? super T>接口,为返回比较器的参数类型,需要是可比较的(即自身带有Comparable.compareTo方法),参考Comparable接口。返回一个与参数自然序比较逻辑相反的比较器,有o1.compareTo(o2) == reverseOrder().compare(o2, o1)。参考Collections.reverseOrder方法。

若返回比较器中参数为空导致NullPointerException异常,这些异常会交给返回比较器的调用方处理。

naturalOrder

public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
    return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
}

静态方法,传入泛型TT继承Comparable<? super T>接口,为返回比较器的参数类型,需要是可比较的(即自身带有Comparable.compareTo方法),参考Comparable接口。返回一个与参数自然序比较逻辑相同的比较器,有o1.compareTo(o2) == naturalOrder().compare(o1, o2)。参考Comparators.NaturalOrderComparator枚举类。

若返回比较器中参数为空导致NullPointerException异常,这些异常会交给返回比较器的调用方处理。

nullsFirst

public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) {
    return new Comparators.NullComparator<>(true, comparator);
}

静态方法,传入泛型T,为返回比较器的参数类型。返回一个比较器(空值比较器),比较参数含空值时空值为小;比较参数均非空时,comparator为空时比较结果相等,comparator非空时比较逻辑同comparator。参考Comparators.NullComparator类。

若返回比较器中出现异常,那么这些异常会交给返回比较器的调用方处理。

nullsLast

public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) {
    return new Comparators.NullComparator<>(false, comparator);
}

静态方法,传入泛型T,为返回比较器的参数类型。返回一个比较器(空值比较器),类似nullsFirst方法,不同的是,比较参数含空值时空值为大。

comparing

public static <T, U> Comparator<T> comparing(
        Function<? super T, ? extends U> keyExtractor,
        Comparator<? super U> keyComparator)
{ /*...*/ }

静态方法,传入泛型TUT为返回比较器的参数类型,U为比较的参数经过keyExtractor函数式计算的结果的类型。返回比较器(实现Serializable接口)的比较结果同原参数经过keyExtractor函数式计算的keyComparator比较器的比较结果。若keyExtractorkeyComparator为空,则抛出NullPointerException异常。

若返回比较器中出现异常,那么这些异常会交给返回比较器的调用方处理。

public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
        Function<? super T, ? extends U> keyExtractor)
{ /*...*/ }

静态方法,传入泛型TUT为返回比较器的参数类型,U继承Comparable<? super U>接口,为比较的参数经过keyExtractor函数式计算的结果的类型,需要是可比较的(即自身带有Comparable.compareTo方法)。返回比较器(实现Serializable接口)的比较结果同原参数经过keyExtractor函数式计算的自然序比较结果。参考Comparable接口。若keyExtractor为空,则抛出NullPointerException异常。

若返回比较器中出现异常,那么这些异常会交给返回比较器的调用方处理。

comparingInt

public static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) { /*...*/ }

静态方法,传入泛型T,为返回比较器的参数类型。返回比较器(实现Serializable接口)的比较结果同原参数经过keyExtractor函数式计算的的自然序比较结果。类似<T, U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T, ? extends U> keyExtractor)方法,不同的是,keyExtractor函数式为整型“特例化”的函数式。

comparingLong

public static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor) { /*...*/ }

静态方法,传入泛型T,为返回比较器的参数类型。返回比较器(实现Serializable接口)的比较结果同原参数经过keyExtractor函数式计算的的自然序比较结果。类似<T, U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T, ? extends U> keyExtractor)方法,不同的是,keyExtractor函数式为长整型“特例化”的函数式。

comparingDouble

public static<T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor) { /*...*/ }

静态方法,传入泛型T,为返回比较器的参数类型。返回比较器(实现Serializable接口)的比较结果同原参数经过keyExtractor函数式计算的的自然序比较结果。类似<T, U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T, ? extends U> keyExtractor)方法,不同的是,keyExtractor函数式为双精度浮点型“特例化”的函数式。


总结

新人源码理解,望大家多多指点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值