java - 如何解释方法比较的参数(Function<?super T,?extend U> keyExtractor)?

标签 java generics lambda java-8 generic-constraints

方法的完整签名:

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/

相关文章:

java - Android:在使用接口(interface)测试类期间提供模拟实现

java - 如何动态转换/确保具有不同泛型的集合的类型安全

c# - C# lambda 表达式是否可以返回 void?

scala - lambdas 在 Scala 中是如何工作的,它们是在匿名类之上运行的吗?

c++ - const std::unordered_map<char, int>' as ‘this’ 参数丢弃 lambda 中的限定符

java - 具有泛型的模拟方法并在返回类型中扩展

java - 当按钮的setOnClickListener第二次执行时

java - jenkins CI 中服务器节点未连接

java - 通用方法 - 不能应用于给定类型

Java 类型转换和原始类型