Java Lambda 表达式是否类似于 Groovy 闭包的逻辑?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25565020/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is Java Lambda expression is similar logic of Groovy closure?
提问by Sai Ye Yan Naing Aye
I learn about java 8 new feature Lambda expressions. So this is my "HelloWorld" class using Lambda expression
我了解了 Java 8 新功能Lambda 表达式。所以这是我使用 Lambda 表达式的“HelloWorld”类
public class LambdaHelloWorld {
interface HelloWorld {
String sayHello(String name);
}
public static void main(String[] args) {
HelloWorld helloWorld = (String name) -> { return "Hello " + name; };
System.out.println(helloWorld.sayHello("John Doe"));
}
}
This style is so similar to Groovy closure. This is groovy "HelloWorld"
这种风格与 Groovy 闭包非常相似。这是时髦的“HelloWorld”
def sayHello(name) {
println("Hello $name!")
}
def clos = {name -> sayHello(name)} clos.call('John Doe')
I think these two codes are less difference between each others.Is Java Lambda expression is similar logic or style of Groovy closure?
我认为这两个代码彼此之间的差异较小。Java Lambda表达式是否类似于Groovy闭包的逻辑或风格?
回答by jst
Implementing a so-called functional interface in Java 8 (with lambdas) or in Groovy (with closures) looks quite the same, but underlying mechanisms are pretty different. Let's take the java.util.function.Consumer
functional interface as an example. We use it to call the new Java 8 forEach()
method on a hypothetic java.util.List
instance called myList
.
在 Java 8(使用 lambdas)或 Groovy(使用闭包)中实现所谓的函数式接口看起来完全相同,但底层机制却大不相同。我们以java.util.function.Consumer
函数式接口为例。我们使用它forEach()
在java.util.List
名为的假设实例上调用新的 Java 8方法myList
。
In Java it looks like this:
在 Java 中,它看起来像这样:
myList.forEach ((s) -> System.out.println(s));
The same in Groovy:
在 Groovy 中也是如此:
myList.forEach { s -> println s }
Both compilers generate new Classes from the lambda / closure code. The class generated by Java 8 implements the target interface (Consumer
in this case), not derived from anything, similar to an embedded anonymous class like this:
两个编译器都从 lambda / 闭包代码生成新的类。Java 8 生成的类实现了目标接口(Consumer
在这种情况下),不是从任何东西派生的,类似于这样的嵌入式匿名类:
myList.forEach(new Consumer<Object>() {
@Override
public void accept (Object s) {
System.out.println(s);
}
});
In contrast, what Groovy generates looks a little bit like the following:
相比之下,Groovy 生成的内容看起来有点像以下内容:
myList.forEach (new Closure(this) {
void doCall(Object s) {
println s
}
}
This creates an anonymous class derived from groovy.lang.Closure
that does notimplement any specific interface. Nevertheless, it can be used as parameter here. This is possible because Groovy generates a dynamic proxy object at runtime, implementing the ′Consumer′ interface and forwarding any calls to the generated Closure instance.
这将创建来源于一个匿名类groovy.lang.Closure
,它没有实现任何特定的接口。尽管如此,它可以在这里用作参数。这是可能的,因为 Groovy 在运行时生成动态代理对象,实现“Consumer”接口并将任何调用转发到生成的 Closure 实例。
As a consequence, you can replace Java 8 lambdas by Groovy closures, but not the other way round. When you want to use a Groovy API in Java 8 code, you cannot call a method expecting a Closure with a lambda expression. Closure
isn't a functional interface but an abstract class, and that can simply not be implemented by a lambda expression.
因此,您可以用 Groovy 闭包替换 Java 8 lambdas,但不能反过来。当您想在 Java 8 代码中使用 Groovy API 时,您不能使用 lambda 表达式调用需要闭包的方法。Closure
不是函数式接口而是抽象类,并且它不能由 lambda 表达式实现。
回答by Marko Topolnik
Java's lambdas are closures as well. These are the same feature on an abstract level, but in detail and depending on exact version, Groovy may just be creating ad-hoc implementing classes, whereas Java 8 specifies a complete mechanism, consisting of lambda Metafactory, lambda factory, and a mechanism involving invokedynamic
to acquire the lambda Metafactory.
Java 的 lambdas 也是闭包。这些在抽象层面上是相同的特性,但在细节上并取决于确切的版本,Groovy 可能只是创建临时实现类,而 Java 8 指定了一个完整的机制,由 lambda Metafactory、lambda factory 和一个机制组成invokedynamic
收购 lambda Metafactory。
回答by Scott Langeberg
I wanted a simple local closure to pass / execute. I never found this answer anywhere, so adding my spin, so you can see actual mapping from local groovy closure to local java lambda.
我想要一个简单的本地闭包来传递/执行。我从来没有在任何地方找到这个答案,所以添加我的自旋,这样你就可以看到从本地 groovy 闭包到本地 java lambda 的实际映射。
Groovy:
常规:
def clos = {name -> sayHello(name)}
clos('John Doe')
Java:
爪哇:
Consumer<String> clos = name -> sayHello(name);
clos.accept("John Doe");
The key being that bloody Consumer interface with accept() method to invoke - you must match the params and return type of your Java lambda based on their pre-canned Function interfaces (java.util.function.*). That bit is a drag, compared to untyped Groovy version.
关键是带有要调用的 accept() 方法的血腥 Consumer 接口 - 您必须根据它们的预装函数接口 (java.util.function.*) 匹配 Java lambda 的参数和返回类型。与无类型的 Groovy 版本相比,这一点是一个阻力。