参考 Comparator 接口的静态方法 comparing

Producer Extends, Consumer Super

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static <T, E extends Comparable<? super E>> Comparator<T> comparing(Function<? super T, ? extends E> keyGenerator) {
Comparator<T> comparator1 = new Comparator<T>() {
@Override
public int compare(T o1, T o2) {
// 假设 keyGenerator 的定义接受一个 T 的父类型, 如 FatherT
// 此时 o1 是 T 类型的,是可以作为 keyGenerator.apply(FatherT fatherT) 的参数的
// 会进行向上转换,是合理有效的,任何父类引用都可以指向子类对象(父类的方法都会被子类继承,所以是合理的)
return keyGenerator.apply(o1).compareTo(keyGenerator.apply(o2));
}
};

// lambda 表达式写法
Comparator<T> comparator = (c1, c2) -> keyGenerator.apply(c1).compareTo(keyGenerator.apply(c2));
return comparator;
}

如果要返回一个 T 类型的 Comparator, 也就是 Comparator, 其负载类型为 T,comparing 是可以传入一个 Functinon<? super T, ? extends E> 的实例的,Functinon 的负载类型的第一个参数类型可以为 T 的任何父类型,也就是此 Functinon 的 apply() 方法可以接受任何 T 的父类对象。

在返回一个 Comparator 对象时,Functinon 函数会接受一个 T 对象实例,此时,会发生向上转换:

1
2
3
4
5
6
7
8
9
10
// 方法签名接受一个 Father 对象
public void printField(Father father) {
System.out.pritln(father.getField());
}

public void test() {
Son = new Son();
// 传入一个子类 Son 对象
printField(son);
}
1
2
3
4
5
6
7
public static void dateTest() {
Function<Circle, Integer> circleFunc = circle -> circle.getR().length();

// 当左边的类型为 CircleSubClass 时, keyGenerator 的负载类型可以是 CircleSubClass 的任何父类型
// 当右边 keyGenerator 的负载类型是 Circle 时,左边的 Comparator 负载类型可以是 Circle 的任何子类
Comparator<CircleSubClass> comparing = comparing(circleFunc);
}