我无法理解方法签名:
static <T,U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T,? extends U> keyExtractor)
对super
,extends
,通配符(?
)和多个尖括号感到困惑。请不要误会我的意思,我了解基本的泛型。在这里使用的是较高的结构使我感到困惑。
答案 0 :(得分:2)
该函数的基本形式是
static <T, U> Comparator<T> comparing(Function<T, U> extractor)
稍后我们将处理更细粒度的修改。以上是按顺序说的:
static
:虽然简单明了,但重要的是,这意味着该函数未绑定到其对象实例的类型,因此即使Comparator
被定义并实例化为Comparator<T>
我们仍然在...中写T
。
<T, U>
:这告诉我们函数本身在类型T
和U
上是通用的。这就像您编写class <T, U> MyClass
时一样-您要说这些类型将定义函数其余部分的行为。在这种情况下,这些类型定义了函数的参数,并将根据我们提供的参数推断。如果将Function<Foo,Bar>
赋予comparing()
,则编译器将推断T = Foo.class
和U = Bar.class
。
Comparator<T>
:返回类型,可以比较T
的事物;相当简单。
Function<T, U>
:从T
到U
的映射;相当简单。
剩下的:
<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}使用。