我如何解释方法 compare(Function<? super T,? extends U> keyExtractor) 的参数?

问题描述

方法的完整签名:

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

我正在学习 lambda 表达式,我有一段代码可以比较员工列表并按姓名字段对其进行排序:

List<Employee> employees = new ArrayList<>();

Collections.sort(employees,Comparator.comparing(Employee::getName));

代码运行良好,但我查看了文档中的 Comparator 功能接口,并找到了方法“comparing()”的签名。

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

我没有得到 compare() 的参数。我怎么知道参数接受 lambda 表达式?以及如何解释约束:超级T,?扩展 U> keyExtractor?

我知道 super 的意思是?在层次继承中必须是类型 T 或以上,并且 ?在层次继承中也必须是 U 类型及以下类型。但我们如何在我的例子中解释这一点?

可以这样解释:?继承链中必须是Employees及以上类型,并且继承链中name字段必须是Employees或以下类型?要么 ?必须是类型 Array List 及以上和 ?必须是类型员工列表及以下?

解决方法

我怎么知道参数接受 lambda 表达式?

通过查看它接受的参数的 interface。在这种情况下,参数类型是 Function,它是一个函数式接口(这个名称与接口的名称没有任何联系——你可以随意命名你的接口)。 函数式接口是一个只有一个未实现功能的interface(额外的区别来自于interface可以有{{1 }} 实现)。

看看default

Function

只有一个未实现的方法 - 它称为 @FunctionalInterface public interface Function<T,R> { R apply(T t); default <V> Function<V,R> compose(Function<? super V,? extends T> before) { Objects.requireNonNull(before); return (V v) -> apply(before.apply(v)); } default <V> Function<T,V> andThen(Function<? super R,? extends V> after) { Objects.requireNonNull(after); return (T t) -> after.apply(apply(t)); } static <T> Function<T,T> identity() { return t -> t; } } 。当您创建一个应该是 apply 的 lambda 时,该 lambda 的主体将用于实现 Function

您可能对 apply 感到困惑 - 它不是必需的。这只是为了方便起见的注释。


关于 @FunctionalInterface,这些是对泛型类型的限制。这意味着所说的 <? super T,? extends U> 需要一个超类型 Function 的参数,并将返回从 T 派生的内容。这是一个相当复杂的话题。你可以read more about it here

,

方法的完整签名:

public static > 比较器比较( 功能超级T,?扩展 U> keyExtractor)

Citing from docs:

接受一个函数,该函数从类型 T 中提取 Comparable 排序键,并返回一个比较器,该比较器通过该排序键进行比较。

所以,到目前为止我们知道 compare() 方法接受一个函数作为参数,这是@Fureeish 在之前的答案中解释过的函数接口。因为 lambda 表达式是围绕函数式接口构建的,所以我们知道我们可以将它用作参数。

类型参数:

T - 要比较的元素类型 U - Comparable 排序键的类型

T,关于上面的定义是Employee类型的,因为我们要比较雇员或对象的类型,他们的类是Employee的超类。 ? super T,表示占位符?必须是继承链中的类型 T 或以上。

U,是String类型,它是“name”字段,String实现了Comparable(see docs),尊重方法定义:

public static >比较器

参数方法返回一个比较器,通过提取的键进行比较。