Anonimato y lambda
Introducción
Hasta ahora, los métodos Java que hemos desarrollado sólo han recibido variables como parámetros. Este capítulo da un paso hacia la programación funcional, mostrando cómo pasar también ’procesos’ como parámetros.
Sí, pero ¿para qué sirve?
El objetivo principal de esto es reducir su código, aunque tendrá que aprender un poco sobre estas nuevas sintaxis que estamos a punto de descubrir.
Este capítulo se divide en dos partes. La primera presenta las clases anónimas, que fueron la primera forma concisa de pasar procesos como parámetros. La segunda parte presenta las expresiones lambda, disponibles desde Java 8 y que simplifican aún más el código.
Clases anónimas
1. Matar dos pájaros de un tiro
La clase anónima es una clase declarada e instanciada al mismo tiempo.
Implementa una interfaz conocida o extiende una clase existente. Sólo puede implementar una interfaz o extender una clase a la vez.
La clase anónima es una clase anidada (véase el capítulo Creación de clases), que no tiene nombre. Su instancia está asociada a la de la clase que la contiene.
Sólo es útil si se necesita una única vez. Si la funcionalidad que soporta se solicita en varios lugares de su código, entonces es preferible escribir una clase con nombre como hemos hecho hasta ahora. Así se evita duplicar código innecesariamente.
2. Sintaxis especial
Una clase anónima es una expresión y su declaración/instanciación se realiza como una llamada a un constructor.
Sintaxis de la declaración
new <nombre de la clase a extender o interfaz a implementar>()
{
// cuerpo de la clase anónima
};
El operador new inicia la expresión, seguido del nombre de la clase que se va a extender o del nombre de la interfaz que se va a implementar. Por supuesto, la clase o interfaz en cuestión debe ser conocida. Los paréntesis que siguen pueden contener cualquier parámetro en el caso de una extensión de clase. Recuerde que una interfaz no tiene constructor. A continuación, viene el cuerpo de la clase, que puede contener métodos y datos. Por último, como la clase anónima es una expresión, la secuencia termina con un punto y coma (;).
Ejemplo
Animal perro = new Animal(){
@Override
public String Expresion() {
return "Ouaf Ouaf";
}
};
Aquí, la clase anónima extiende la superclase Animal «sobre la marcha», asumiendo todo su contenido y redefiniendo su comportamiento Expresion. La instancia así creada de esta clase «anónima» se almacena...
Expresiones lambda
1. El concepto
Acabamos de ver cómo se pueden utilizar las clases anónimas para codificar comportamientos rápidamente. Esta herramienta, que apareció con la versión 1.1 de Java, sigue siendo un poco engorrosa de utilizar. Diecisiete años después, en 2014, llega Java 8 con sus expresiones lambda presentadas como una gran novedad. Una gran novedad en el ámbito de Java, porque los desarrolladores de C# ya llevaban lidiando con las expresiones lambda desde 2007, aunque con algunas diferencias.
Con las expresiones lambda, pasamos de la declaración/instanciación de la clase anónima a la de la función anónima. El resultado es un código aún más conciso, fácil de escribir, leer y mantener.
2. Interfaces "funcionales" como modelos
Tomemos un ejemplo de implementación de una interfaz por una clase anónima y veamos cómo las expresiones lambda pueden ayudarnos a hacer su código más "digerible"…
En primer lugar, consideremos una interfaz que contiene un único método abstracto:
public interface IMath {
int Calcular(int i, int j);
}
Ahora vamos a crear una clase anónima alrededor de esta interfaz y luego usarla como vimos en la primera parte de este capítulo.
public void Demo1(int a, int b){
// Modo clase anónima
IMath adicion_clase_anonima = new IMath(){
@Override
public int Calcular(int i, int j){
return i+j;
}
};
System.out.println(adicion_clase_anonima.Calcular(a,b));
}
Y aquí está el código equivalente en forma de expresión lambda:
public void Demo1(int a, int b){
// Modo expresión lambda
IMath adicion_expression_lambda = (i,j)->i+j;
System.out.println(adicion_expresion_lambda.Calcular(a,b));
}
¿Cómo se consigue este atajo sintáctico que simplifica tanto las cosas? Veámoslo elemento por elemento:
-
Como la expresión lambda es de tipo interfaz, escribimos su variable en IMath.
-
El signo = precede a la implementación....