为什么Java PriorityQueue实现使用Comparator<?超级E>而不是简单的Comparator<E>



jdk8中定义的Java PriorityQueue源代码使用了一个类似定义的比较器

/**
* The comparator, or null if priority queue uses elements'
* natural ordering.
*/
private final Comparator<? super E> comparator;

此处的源代码(第108行(

为什么需要使用一种类型的超级E而不是简单的E.

换句话说,为什么不像下面这样定义比较器呢:

private final Comparator<E> comparator;

这种额外抽象背后的动机是什么?

因为为什么不呢。

给定一个可以比较任意2个CharSequence对象的比较器(CharSequence是一个接口;String、StringBuilder和其他一些东西实现了它(,那么。。当您需要只比较字符串时,这同样好。所有字符串也是CharSequences,因此一个比较器可以告诉你任何2个charsequence对象哪一个"先到",可以很好地完成这项工作。

默认情况下,泛型是不变的,所以如果你有一个PriorityQueue<String>,并且它按照你想要的方式工作,它看起来就像Comparator<E>,意思是Comparator<String>,而Comparator<CharSequence>与之不兼容。就像将String传递给想要Integer对象的方法一样,它只是不编译。

因此,<? super E>,以便可以传递Comparator<CharSequence>

当然,它不会经常出现,但这样做"更正确"。如果你碰巧有一个CharSequences的比较器,却不能用它为PriorityQueue<String>供电,我相信你会感到惊讶。

最新更新