Замыкания в groovy против закрытия в java 8 (лямбда-выражения)?

Учитывая doSomething(Function foo) { println foo(2) }

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

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

Есть ли разница между двумя?

Ответ 1

В Groovy замыкания являются гражданами первого класса типа groovy.lang.Closure, тогда как lambdas в Java 8 являются фактическими экземплярами интерфейса метода по умолчанию, который они представляют.

Это означает, что вам нужно использовать ключевое слово as в Groovy (как вы показали), но, в качестве альтернативы, в 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 ) ;
    }
}

Очевидно, вы также можете объявить реализацию по умолчанию в интерфейсах, которые я здесь не показывал...

Не уверен, что это все различия, но это, по крайней мере, разница; -)

Ответ 2

  • В Java Lambda Expressions нет способа ссылаться на параметры лямбда-выражений по умолчанию. В Groovy есть что-то подобное. Я думаю, что это "это".
  • В Java Lambda выражения представляют собой удобный способ реализации классов и интерфейсов Single Abstract Method. Поэтому, если вам нужно создать выражение лямбда для чего-то, у вас должен быть установлен интерфейс SAM.
  • В Java выражения Lambda могут захватывать только те переменные, которые являются фактически окончательными.
  • В Java существует альтернативный способ представления выражения Lambda, используя что-то, называемое ссылкой на методы. Поэтому, если у вас есть лямбда-выражения, такие как {() -> new MyObject();}, его можно записать как MyObject::new. Я думаю, что не все лямбда-выражения могут быть представлены с помощью ссылок на методы.

Я не думаю, что было бы идеально сравнить поддержку выражения лямбда в Java 8 с поддержкой более зрелой поддержки Groovy или Scala. Это первый шаг для Java для представления лямбда-выражений, поэтому в будущем мы можем ожидать более зрелую поддержку лямбда-выражений.