Java的Comparator.comparing方法中泛型的语义

时间:2018-03-24 17:05:54

标签: java generics

在浏览JAVA文档时,我发现了以下比较方法的签名

 static <T,U extends Comparable<? super U>>
Comparator<T> comparing(Function<? super T,? extends U> keyExtractor)

我知道U应该具有可比性,但使用

的意义是什么
Comparable<? super U>

而不是仅使用Comparable<U>

同样,使用Function<? super T,? extends U> keyExtractor的意义何在? 超过Function<T,U> keyExtractor

2 个答案:

答案 0 :(得分:2)

使用Producer Extends Consumer Super(PECS)的原则。

基本上,PECS表示如果将通用参数用作方法的参数类型,则应使用逆变,即super。如果它用作返回值类型,则应使用协方差,即extends

U被限制为extend Comparable<? super U>。在这里,super用于实现U的逆转。因此,即使UString,您也可以传递Comparable<Object>

Function参数类型为Function<? super T,? extends U>,以实现T(消费者,在Function的参数类型中使用)和U上的协方差的逆转(用于返回值类型Function)。这样,即使Function<Object, String>TStringU,您也可以传递Object

重要的是没有extendssuper,这称为不变性。这意味着您必须传递完全通用参数类型TU的实例,这会降低灵活性。

要了解有关PECS的更多信息,请访问here

答案 1 :(得分:1)

通常意味着超类可以实现Comparator。例如,如果Number实现Comparable,则List<Integer>.sort(null)是可以的,因为可比较的是在超类Integer上。

除此之外,比较器必须是Comparable<Integer>,因为可比较实际上是Comparable<Number>,所以它不起作用。