Java Comparator.comparing()类型签名是什么意思?

时间:2019-03-14 17:44:02

标签: java generics java-8

我无法理解方法签名:

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

superextends,通配符(?)和多个尖括号感到困惑。请不要误会我的意思,我了解基本的泛型。在这里使用的是较高的结构使我感到困惑。

1 个答案:

答案 0 :(得分:2)

该函数的基本形式是

static <T, U> Comparator<T> comparing(Function<T, U> extractor)

稍后我们将处理更细粒度的修改。以上是按顺序说的:

  • static:虽然简单明了,但重要的是,这意味着该函数未绑定到其对象实例的类型,因此即使Comparator被定义并实例化为Comparator<T>我们仍然在...中写T

  • <T, U>:这告诉我们函数本身在类型TU上是通用的。这就像您编写class <T, U> MyClass时一样-您要说这些类型将定义函数其余部分的行为。在这种情况下,这些类型定义了函数的参数,并将根据我们提供的参数推断。如果将Function<Foo,Bar>赋予comparing(),则编译器将推断T = Foo.classU = Bar.class

  • Comparator<T>:返回类型,可以比较T的事物;相当简单。

  • Function<T, U>:从TU的映射;相当简单。

剩下的:

  • <T, U>实际上是<T,U extends Comparable<? super U>>,这意味着T是什么,U需要扩展Comparable(即可比),即使它是根据它的超级类型真的可以比较。例如,我可能有Bar extends Foo,其中Foo implements Comparable;通过将它们视为Bar,我仍然可以比较类型为Foo的对象。这是一个具体示例:

    • 让我们上一堂课MyBigInt implements Comparable<MyBigInt>。假设我们已经实现了Comparable接口,并且根据其整数值正确比较了我们的类。
    • 接下来让我们创建一个新的类MyBigColorfulInt extends MyBigInt,它添加了一些愚蠢的非整数功能-重要的是,它实现Comparable<MyBigColorfulInt>,但作为{{ 1}}它确实(暗中)实施MyBigInt
    • 现在,让我们回到关于Comparable<MyBigInt>的问题:说我们的类型<T, U extends Comparable<? super U>内包含类型T的字段,我想 compare < / em>类型为MyBigColorfulInt的对象,基于其T成员(这是MyBigColorfulInt)。 如果签名为U,我们将很不走运:U extends Comparable<U>未实现MyBigColorfulInt。但是,无论如何,我们确实想将Comparable<MyBigColorfulInt>MyBigColorfulInt进行比较。 MyBigInt让我们免费进行此操作,因为它允许基于U extends Comparable<? super U>>的超类进行比较。如果不是这样,我们可以做的最好的事情就是在比较之前将每个U强制转换为MyBigColorfulInt,这不是很好。
  • MyBigInt实际上是Function<T, U>,因此一次:

    • Function<? super T,? extends U>与上面关于<? super T>的观点类似,这实际上意味着我们必须能够从{{1 }},如果我们提取的内容确实来自U的超类也可以。

    • U也与上述要点类似(以不同的方式):我们的函数需要提取T类型的东西进行比较,但是如果我们要重新提取是T的后代,只要它可以作为我们<? extends U>的比较{em}使用