Java lambda 表达式、转换和比较器 [英] Java lambda expressions, casting, and Comparators

查看:12
本文介绍了Java lambda 表达式、转换和比较器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在查看 Map 接口的 Java 源代码时遇到了这个小代码片段:

I was looking through Java source code for the Map interface and ran into this little snippet of code:

    /**
     * Returns a comparator that compares {@link Map.Entry} in natural order on value.
     *
     * <p>The returned comparator is serializable and throws {@link
     * NullPointerException} when comparing an entry with null values.
     *
     * @param <K> the type of the map keys
     * @param <V> the {@link Comparable} type of the map values
     * @return a comparator that compares {@link Map.Entry} in natural order on value.
     * @see Comparable
     * @since 1.8
     */
    public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> comparingByValue() {
        return (Comparator<Map.Entry<K, V>> & Serializable)
            (c1, c2) -> c1.getValue().compareTo(c2.getValue());
    }

从方法声明中,我了解到这是一个通用方法,它返回一个类型的 Comparator,该类型要么是从传递给它的映射条目中推断出来的,要么是在方法中明确提供的.

From the method declaration I get that this is a generic method that returns a Comparator of a type that is either inferred from the map entries passed to it or explicitly provided in the method.

真正让我失望的是返回值.看来 lambda 表达式

What's really throwing me off is the return value. It appears that the lambda expression

(c1, c2) -> c1.getValue().compareTo(c2.getValue());

显式转换为 Comparator>.对吗?

is explicitly cast to a Comparator<Map.Entry<K, V>>. Is this right?

我还注意到明显的演员阵容包括 &可序列化.我以前从未见过接口与类型转换中的类相结合,但它在编译器中看起来像以下有效:

I also noticed that the apparent cast includes & Serializable. I've never seen an interface combined with a class in a cast before, but it looks like the following valid in the compiler:

((SubClass & AnInterface) anObject).interfaceMethod();

虽然以下方法不起作用:

Although the following doesn't work:

public class Foo {
    public static void main(String[] args) {
        Object o = new Foo() {
            public void bar() {
                System.out.println("nope");
            }
        };
        ((Foo & Bar) o).bar();
    }   
}

interface Bar {
    public void bar();
}

那么,两个问题:

  1. 向演员表添加接口应该如何工作?这是否只是强制执行接口方法的返回类型?

  1. How does adding an interface to a cast supposed to work? Does this just enforce the return type of an interface's method?

您能否将 Lambda 表达式转换为 Comparator?他们还能扮演什么角色?或者 lambda 表达式本质上只是一个 Comparator?有人可以澄清这一切吗?

Can you cast a Lambda expression to a Comparator? What else can they be cast as? Or is a lambda expression essentially just a Comparator? Can someone clarify all of this?

推荐答案

向演员表添加接口应该如何工作?

How does adding an interface to a cast supposed to work?

这具有强制转换的语法,但它实际上定义了您通过类型接口创建的 lambda 的类型.IE.您不是在创建一个对象的实例,然后将其转换为另一种类型.

This has the syntax of a cast, however it is actually defining the type of the lambda you are creating via type interface. I.e. you are not creating an instance of a object which is then being cast to another type.

这是否只是强制执行接口方法的返回类型?

Does this just enforce the return type of an interface's method?

这实际上定义了 lambda 将在运行时构建的类型.有一个 LambdaMetaFactory 在运行时获取此类型并生成如果类型包括 Serializable,则额外的代码.

This actually defines the type the lambda will be built as at runtime. There is a LambdaMetaFactory which obtains this type at runtime and generates extra code if the type includes Serializable.

能否将 Lambda 表达式转换为比较器?

Can you cast a Lambda expression to a Comparator?

您只能将引用转换为对象已经存在的类型.在这种情况下,您定义要创建的 lambda 必须是 Comparator.你可以使用任何一个只有一个抽象方法的类型.

You can only cast a reference to a type the object is already. In this case you are defining the lambda to be created must be Comparator. You can use any type which has exactly one abstract method.

或者是一个 lambda 表达式本质上只是一个比较器?

Or is a lambda expression essentially just a Comparator?

可以在不同的上下文和不同的界面中使用(复制+粘贴)相同的 lambda 代码而无需更改.它不必是 Comparator,正如您将在 JDK 的许多其他示例中看到的那样.

The same lambda code could be used (copy+pasted) in different contexts and different interfaces without change. It doesn't have to be a Comparator as you will see in many other examples in the JDK.

我觉得有趣的是Stream 上的count 方法.

One I find interesting is the count method on a Stream.

这篇关于Java lambda 表达式、转换和比较器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆