如何解释方法比较的参数(函数< ?超级t,?扩展(u>keyextractor)?

iyfamqjs  于 2021-06-29  发布在  Java
关注(0)|答案(2)|浏览(498)

方法完整签名:

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或以下类型?或者?必须是类型数组列表和上面的?必须是员工列表及以下类型?

m0rkklqb

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方法返回一个比较器,通过提取的键进行比较。

2guxujil

2guxujil2#

如何知道参数接受lambda表达式?
通过看 interface 它接受的论点。在本例中,参数类型为 Function ,这是一个功能接口(此名称实际上与接口名称没有任何连接-您可以根据需要命名接口)。功能接口是 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的主体将用于实现 apply .
你可能会对 @FunctionalInterface -这不是必需的。这只是为了方便起见的注解。
关于 <? super T,? extends U> ,这些是泛型类型的约束。意思是说 Function 需要一个超类型的参数 T 并将返回从 U . 这是一个相当复杂的主题。你可以在这里了解更多。

相关问题