文章目录
前言
本文章帮助大家对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);
比较o1
、o2
,若o1
小于o2
,返回负数;若o1
等于o2
,返回0;若o1
大于o2
,返回正数,即提供函数逻辑。若参数为空但比较器不允许为空,抛出NullPointerException
异常;若因参数的类型而不能比较,抛出ClassCastException
异常。
注意:比较需要有“相反性”(a ≥ b
⇔
\Leftrightarrow
⇔b ≤ a
)、“传递性”(a ≥ b ≥ c
⇒
\Rightarrow
⇒a ≥ c
)等。
强烈建议compare(x, y)==0
和x.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));
}
传入泛型U
,U
继承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(); }
静态方法,传入泛型T
,T
继承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;
}
静态方法,传入泛型T
,T
继承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)
{ /*...*/ }
静态方法,传入泛型T
、U
。T
为返回比较器的参数类型,U
为比较的参数经过keyExtractor
函数式计算的结果的类型。返回比较器(实现Serializable
接口)的比较结果同原参数经过keyExtractor
函数式计算的keyComparator
比较器的比较结果。若keyExtractor
或keyComparator
为空,则抛出NullPointerException
异常。
若返回比较器中出现异常,那么这些异常会交给返回比较器的调用方处理。
public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
Function<? super T, ? extends U> keyExtractor)
{ /*...*/ }
静态方法,传入泛型T
、U
。T
为返回比较器的参数类型,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
函数式为双精度浮点型“特例化”的函数式。
总结
新人源码理解,望大家多多指点。