Java的lambda语法有什么细分? [英] What is the breakdown for Java's lambda syntax?

查看:75
本文介绍了Java的lambda语法有什么细分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请解释Java 8的lambda方法的语法。

Please explain the syntax for Java 8's lambda methods.

lambda函数有很多解释,但是我找不到对语法的详尽解释,我发现学习正确复制语法非常困难,因为我不理解为什么它们是按原样编写的。

There are a lot of explanations out there for what lambda functions are, but I can't find a thorough explanation of the syntax, and I am finding it very difficult to learn to replicate the syntax correctly because I don't understand why they're written as they are.

这是我遇到的一个常见案例,由NetBeans提供:

Here's a common case that I run into, courtesy NetBeans:

public static void main(String[] args) {
    SwingUtilities.invokeLater(() -> {
        new MainAppJFrame();
    });
}

所以不知何故,以下lambda表达式正在解析为匿名 Runnable object的run()方法:

So somehow, the following lambda expression is resolving into an anonymous Runnable object's run() method:

() -> {
    // do stuff
}

- > 是正确的lambda语法,对吧?花括号只是包含匿名方法代码。括号是否为空参数,因为在这种情况下我们创建了一个 Runnable.run()方法?

The -> is the lambda syntax proper, right? And the curly braces are simply containing the anonymous method code. Are the parentheses an empty argument, because in this case we're creating a Runnable.run() method?

这对我来说都不太清楚。我假设编译器知道根据 SwingUtilities.invokeLater(Runnable)方法所期望的类型实例化匿名 Runnable ?如果有两个 SwingUtilities.invokeLater 方法只在参数列表中有所不同,会发生什么?显然在这种情况下没有,但在其他地方可能没有:

This is all rather unclear to me. I assume the compiler knows to instantiate an anonymous Runnable based on the type expected by the SwingUtilities.invokeLater(Runnable) method? What would happen if there were two SwingUtilities.invokeLater methods which differ only in parameter list? Obviously there aren't in this specific case, but it's possible elsewhere:

interface ExampleLambdaConsumer {
    public void doSomething(Runnable r);
    public void doSomething(java.lang.reflect.Method m);
}

class C implements ExampleLambdaConsumer {
    // implementations for doSomething methods here

    public static void main(String[] args) {
        doSomething(() -> {
            // lambda method body here
        }
    }
}


推荐答案

语法是:

arguments -> body

其中参数可以是


  • ()

单个变量,如果该变量的类型可以从上下文推断

a single variable if the type of that variable can be inferred from the context

一系列变量,或没有类型,在括号中

a sequence of variables, with or without types, in parentheses

和body可以是表达式,也可以是 {。 ..} 阻止语句。只返回表达式,即() - > 2 相当于( ) - > {return 2;}

and body can be either an expression or a {...} block with statements. The expression is simply returned, i.e. () -> 2 is equivalent to () -> {return 2;}

编辑:在lambda表达式的情况,如() - > f()

In case of lambda expressions like () -> f():


  • 如果 f()返回 void ,它们相当于() - > { F(); }

否则,它们相当于() - > { F(); } () - > {return f(); })。编译器从调用上下文中推断出它,但通常它会更喜欢后者。

otherwise, they are equivalent to either () -> { f(); } or () -> { return f(); }). The compiler infers it from the calling context, but usually it will prefer the latter.

因此,如果您有两种方法: void handle(供应商< T>) void handle(Runnable),然后:

Therefore, if you have two methods: void handle(Supplier<T>) and void handle(Runnable), then:


  • handle(() - > {return f();}) handle(() - > x)将拨打第一个,

handle(() - > {f();} 将拨打第二个,

handle(() - > f())


  • 如果 f()返回 void 或者无法转换为 T 的类型,然后它将调用第二个

  • if f() returns void or a type that is not convertible to T, then it will call the second one

如果 f()返回一个可转换为 T 的类型,那么它将拨打第一个

if f() returns a type that is convertible to T, then it will call the first one

编译器尝试将lambda的类型与上下文匹配。我不知道确切的规则,但答案是:

The compiler tries to match the type of the lambda to the context. I don't know the exact rules, but the answer to:


如果有两个Swin会发生什么gUtilities.invokeLater方法只在参数列表中有所不同?

What would happen if there were two SwingUtilities.invokeLater methods which differ only in parameter list?

是:它取决于那些参数列表。如果另一个 invokeLater 也只有一个参数,那个参数的类型也是一个类型为 void *()<的方法的接口/ code>,那么它会抱怨它无法找出你的意思。

is: it depends on what would be those parameter lists. If the other invokeLater had also exactly one parameter and that parameter would be of type that is also an interface with one method of type void*(), well, then it would complain that it cannot figure out which method you mean.

为什么它们是按原样写的?嗯,我认为这是因为C#和Scala中的语法几乎相同(他们使用 => 而不是 - > )。

Why are they written as they are? Well, I think it's because syntax in C# and Scala is almost the same (they use => rather than ->).

这篇关于Java的lambda语法有什么细分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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