为什么Java PriorityQueue实现使用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;
这个额外抽象背后的动机是什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
因为为什么不呢。
给定一个可以比较任意 2 个 CharSequence 对象的比较器(CharSequence 是一个接口;String、StringBuilder 和其他一些东西实现它),那么……当您只需要比较字符串时,这也同样好。所有字符串也是 CharSequences,因此可以告诉您任何 2 个 charsequence 对象中哪一个“先出现”的比较器可以完美地完成这项工作。
默认情况下,泛型是不变的,因此如果您有一个
PriorityQueue
,并且它按照您想要的方式工作,它看起来像Comparator
,这意味着Comparator
,而Comparator
与之不兼容。就像将String
传递给需要Integer
对象的方法一样,它只是无法编译。因此,
,以便您可以传递
Comparator
。当然,它不会经常出现,但这样“更正确”。我相信,如果您碰巧有一个 CharSequences 比较器,并且无法使用它来驱动
PriorityQueue
,您一定会感到惊讶。Because why not.
Given a comparator that can compare any 2 CharSequence objects (CharSequence is an interface; String, StringBuilder, and a few other things implement it), then.. that is just as good when you have a need to compare only strings. All Strings are also CharSequences, so a comparator that can tell you for any 2 charsequence objects which one 'comes first' can do the job perfectly well.
Generics are invariant by default, so if you have a
PriorityQueue<String>
, and it worked like you want to, it'd look likeComparator<E>
, which meansComparator<String>
, and aComparator<CharSequence>
is not compatible with that. Like passing aString
to a method that wants anInteger
object, it just doesn't compile.Hence,
<? super E>
so that you can pass aComparator<CharSequence>
.It doesn't come up often, of course, but it's 'more correct' this way. I'm sure you'd be surprised if you so happen to have a comparator of CharSequences laying about and can't use it to power a
PriorityQueue<String>
.