在java 8中的groovy和闭包中的闭包(lambda表达式)?

给予doSomething(Function foo) { println foo(2) }

Groovy: doSomething( { it*it } as Function )

Java: doSomething( (x) -> x*x )

这两者有什么区别吗?

在Groovy中,闭包是groovy.lang.Closure类型的一等公民,而Java 8中的lambdas是它们所代表的默认方法接口的实际实例。

这意味着你需要在Groovy中使用as关键字(如你所示),但是在Java中你需要指定一个接口,所以在Groovy中你可以这样做:

 def adder( int i, Closure cl ) { cl( i ) } int v = adder( 2 ) { i -> i + 8 } assert v == 10 

这在Java 8中变成:

 public class Test { interface MyAdder { int call( int i ) ; } public int adder( int i, MyAdder adder ) { return adder.call( i ) ; } public static void main( String[] args ) { int v = new Test().adder( 2, (x) -> x + 8 ) ; System.out.println( v ) ; } } 

显然,你现在也可以在接口中声明默认实现,我在这里没有显示…

不确定这是不是所有的差异,但它至少是一个区别;-)

  • 在Java Lambda表达式中,无法通过默认名称引用lambda表达式的参数。 在Groovy中有类似的东西,我认为它是“它”。
  • 在Java中,Lambda表达式表示实现单个抽象方法类/接口的便捷方式。 因此,如果您必须为某些内容创建lambda表达式,则必须为其定义SAM接口。
  • 在Java中,Lambda表达式只能捕获那些实际上是最终的变量。
  • 在Java中,有一种通过使用名为Method References的方法来表示Lambda表达式的另一种方法。 所以,如果你有一些lambda表达式,如{() -> new MyObject();}它可以写成MyObject::new 。 我认为并非所有lambda表达式都可以使用Method References来表示。

我不认为将Java 8中的lambda表达式支持与更成熟的Groovy或Scala支持进行比较是理想的。 这是Java引入lambda表达式的第一步,因此我们可以期待对lambda表达式有更成熟的支持。