方法完整签名:
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));
代码运行得很好,但我已经查看了docs中的comparator函数接口,并且找到了方法“comparing()”的签名。
comparing(Function<? super T,? extends U> keyExtractor)
我没有得到comparing()的参数。如何知道参数接受lambda表达式?如何解释约束:<?超级t,?扩展u>键提取器?
我知道super的意思是?在层次继承中必须是类型t或更高,并且?在层次继承中也必须是类型u及以下。但在我的例子中,我们怎么能把它简化呢?
可以这样解释:?在继承链中必须是employees及以上类型,并且名称字段必须是employees或以下类型?或者?必须是类型数组列表和上面的?必须是员工列表及以下类型?
2条答案
按热度按时间m0rkklqb1#
方法的完整签名:
公共静态<t,u<?超级u>>比较器比较(函数<?超级t?扩展(u>keyextractor)
引用文件:
接受一个函数,该函数从类型t中提取一个可比较的排序键,并返回一个比较器,该比较器按该排序键进行比较。
因此,到目前为止,我们知道comparing()方法接受一个函数作为参数,这是@fureeish在前面的回答中解释的函数接口。因为lambda表达式是围绕函数接口构建的,所以我们知道可以使用它作为参数。
类型参数:
t-要比较的元素的类型u-可比较排序键的类型
t、 关于上面的定义是employee类型,因为我们要比较employee类型或对象,它们的类是employee的超类?超级t,就是那个占位符?必须是继承链中的类型t或更高。
u、 是类型string,它是“name”字段,string实现了comparable(参见文档),以尊重方法定义:
公共静态<t,u<?超级u>>比较器
parameter方法返回一个比较器,通过提取的键进行比较。
2guxujil2#
如何知道参数接受lambda表达式?
通过看
interface
它接受的论点。在本例中,参数类型为Function
,这是一个功能接口(此名称实际上与接口名称没有任何连接-您可以根据需要命名接口)。功能接口是interface
只有一个未实现的函数(额外的区别来自interface
s可以有default
实现)。看一看
Function
:只有一个未实现的方法-它被称为
apply
. 当你创建一个应该是Function
,lambda的主体将用于实现apply
.你可能会对
@FunctionalInterface
-这不是必需的。这只是为了方便起见的注解。关于
<? super T,? extends U>
,这些是泛型类型的约束。意思是说Function
需要一个超类型的参数T
并将返回从U
. 这是一个相当复杂的主题。你可以在这里了解更多。