为什么Java PriorityQueue实现使用Comparator<?超级E>而不仅仅是比较器

发布于 2025-01-15 18:38:12 字数 563 浏览 3 评论 0 原文

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;

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

The Java PriorityQueue source code defined in jdk8 uses a comparator defined like this

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

Source code here (line 108)

Why the need for using a type that is super of E and not simply E.

In other words, why not define the comparator just like below:

    private final Comparator<E> comparator;

What is the motivation behind that extra abstraction?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

茶色山野 2025-01-22 18:38:12

因为为什么不呢。

给定一个可以比较任意 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 like Comparator<E>, which means Comparator<String>, and a Comparator<CharSequence> is not compatible with that. Like passing a String to a method that wants an Integer object, it just doesn't compile.

Hence, <? super E> so that you can pass a Comparator<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>.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文