Las expresiones lambda son un método sin declaración, es decir, sin modificadores de acceso, que devuelve un valor y un nombre. Permiten escribir un método y utilizarlo inmediatamente.
Esto es útil en el caso de una única llamada a un método, ya que permite reducir el tiempo de declarar y escribir el método sin tener que crear una clase.
Las expresiones lambda en Java por lo general suelen tener la siguiente sintaxis:
(arg1, arg2...) -> { cuerpo }
(tipo1, arg1, tipo2, arg2...) -> { cuerpo }
Ejemplos de expresiones Lambda reales:
(int a, int b) -> { return a + b; }
() -> System.out.println("Hello World");
(String s) -> { System.out.println(s); }
() -> 42
() -> { return 3.1415 };
Las expresiones lambda permiten a Java tener un vínculo funcional que ha faltado durante mucho tiempo. Además aportan funcionalidad al lenguaje otorgando igualdad de condiciones a todos los objetos.
Si bien esto no es 100% cierto, puedes ver que las expresiones lambda no son cierres, pero proporcionan algunas de las mismas características. En Java, las expresiones lambda se encuentran representadas por objetos, y necesitan ser asociadas a un tipo de objeto particular llamado interfaz funcional.
Una estructura de expresiones lambda se caracteriza por:
Los interfaces de marcadores (Marker interface) en Java, son interfaces sin declaración de métodos y campos y se conocen como interfaces vacías. Del mismo modo, las interfaces funcionales son interfaces que tienen un solo método abstracto declarado en ella.
Un ejemplo de interfaz funcional es java.lang.Runnable que solo tiene declarado un método void run(). Otro ejemplo de interfaz funcional es ActionListener, esta interfaz pertenece a la clase Event Listener de la librería java.awt.event.
Solo tiene un método (actionPerformed) que siempre tendremos que implementar cuando hagamos uso de la interfaz. Las expresiones lambda pueden estar implícitamente vinculada a alguna interfaz funcional.
Un programador puede crear una referencia a una interfaz Runnable como se muestra en el siguiente ejemplo:
Runnable r = () -> System.out.println("hola java");
Esta conversión se realiza siempre de forma implícita cuando no se especifica una interfaz funcional:
new Thread(
() -> System.out.println("hola java")
).start();
En el ejemplo anterior, el compilador creará en forma automática la expresión lambda como una implementación de la interfaz Runnable desde el constructor de la clase Thread: public Thread(Runnable r) { }.