Java Lambda 到比较器的转换 - 中间表示

Java Lambda to comparator conversion - intermediate representation

我正在尝试了解 Comparator.comparing 函数的工作原理。我创建了自己的比较方法来理解它。

private static <T,U extends Comparable<U>> Comparator<T> comparing(Function<T,U> f) {
    BiFunction<T,T,Integer> bfun = (T a, T b) -> f.apply(a).compareTo(f.apply(b));
    return (Comparator<T>) bfun;
}

此函数的最后一行抛出异常。

但是,如果我将此功能更改为

private static <T,U extends Comparable<U>> Comparator<T> comparing(Function<T,U> f) {
    return (T a, T b) -> f.apply(a).compareTo(f.apply(b));
}

正如预期的那样工作正常。

第二次尝试使用的中间函数接口是什么,它能够将 lambda 转换为 Comparator

What is the intermediate functional interface which the second attempt uses, which is able to convert the lambda to Comparator?

Comparator 本身。

在第二种方法中,您定义了 Comparator,而不是已转换为 Comparator 的中间对象。

The last line in this function throws an exception.

是的,应该。

如果两个 类 是功能接口并且具有相似的方法(具有相同的签名和相同的 return 类型),这并不意味着它们可以互换使用。


一个有趣的技巧——你可以参考BiFunction<T, T, Integer> bfun的方法apply:

做一个Comparator<T>
private static <T,U extends Comparable<U>> Comparator<T> comparing(Function<T,U> f) {
    final BiFunction<T,T,Integer> bfun = (T a, T b) -> f.apply(a).compareTo(f.apply(b));
    return bfun::apply; // (a, b) -> bfun.apply(a, b);
}

你第二次尝试的中间函数接口就是Comparator<T>:

您可以看到这一点,因为您的代码片段等同于以下内容:

private static <T,U extends Comparable<U>> Comparator<T> comparing(Function<T,U> f) {
    Comparator<T> comparator = (T a, T b) -> f.apply(a).compareTo(f.apply(b));
    return comparator;
}