方法的完整签名:
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 功能接口(interface),并找到了方法“comparing()”的签名。comparing(Function<? super T,? extends U> keyExtractor)
我没有得到 compare() 的参数。我怎么知道参数接受 lambda 表达式?以及如何解释约束: keyExtractor?我知道 super 是什么意思?在层次继承中必须是 T 或以上类型,并且?在层次继承中也必须是 U 及以下类型。但是在我的例子中,我们怎么能引用它呢?
可以这样解释: ?继承链中必须是Employees及以上类型,并且name字段在继承链中必须是Employees或以下类型?或者 ?必须是 Array List 及以上类型并且 ?必须是类型员工列表及以下?
最佳答案
How do I know that the parameter accepts a lambda expersion?
通过查看
interface
它接受的论点。在这种情况下,参数类型是 Function
,这是一个功能接口(interface)(这个名称实际上与接口(interface)名称没有任何联系 - 您可以根据需要命名您的接口(interface))。功能接口(interface)是 interface
只有 一个 未实现的功能(额外的区别来自 interface
s 可以有 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
.当您创建一个应该是 Function
的 lambda 时,该 lambda 的主体将用于实现 apply
.您可能对
@FunctionalInterface
感到困惑- 这不是必需的。为了方便起见,这只是一个注释。关于
<? super T,? extends U>
,这些是对泛型类型的约束。意思是说Function
需要一个父类(super class)型的参数 T
并将返回源自 U
的内容.这是一个相当复杂的话题。您可以read more about it here .
关于java - 如何解释方法比较的参数(Function<?super T,?extend U> keyExtractor)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65468566/