La expresión Lambda es un intento que ha hecho Java en su versión 8 de incluir el paradigma de programación funcional, el cual es un paradigma diferente al de la programación imperativa.

Está basado en un lenguaje matemático formal.

Como ventaja tiene que es mas expresivo, es decir, que nos permite usar menos código para hacer las mismas operaciones y es mucho mas elegante.

Además esta presente en otros lenguajes de programación desde hace tiempo, como por ejemplo: Python o C#.

Expresiones Lambda en otros lenguajes.

Python:
>>>def f(x):
    return x*2

>>> f(3)
6
>>> g= lambda x:x*2 1
>>> g(3)
6
>>> (lambda x:x*2)(3)2
6
C#:
class SimpleLambda {
 static void Main(){
     int[] scores = {90,71,82,93,75,82}
    int highScoreCount =
        scores.Where(n=> n > 80).Count();
    Console.WriteLine("{0} scores are greater than 80", highScoreCount);
 }
}

Expresión Lambda en Java.

La sintaxis de una expresión Lambda es muy sencilla: tendrá siempre 2 partes separadas por una flecha:

    () -> expresion
    (parametros) -> expresion
    (parametros) -> {sentencias;}

Básicamente es un método abstracto, una función sin nombre.

Ejemplo:
() -> new ArrayList<>()
(int a, int b)-> a+b
(a) -> {
        System.out.println(a);
        return true;
       }

Interfaz Funcional

Las expresiones Lambda van intimamente ligada al concepto del interfaz funcional. Se trata de interfaces que tienen solamente un método abstracto, pueden tener un montón de métodos estáticos, por defecto o abstractos pero de la clase object.

Si solamente tienen un método abstracto entonces es una interfaz funcional de forma que se puede utilizar como una expresión Lambda.

En lugar de implementar una clase o una clase anónima, podemos utilziar una expresión Lambda.

Colecciones y forEach.

Las colecciones incorporan en Java 8 el método forEach, el cual nos va a permitir usar expresisones Lambda ya que este método espera una instancia de un objeto tipo Consumer<T> que se puede sustituir al ser una interfaz funcional por una expresión Lambda.

API Stream.

Nos permite trabajar realizar fácilmente operaciones de filtrado, transformación, ordenación, agrupación y presentación de información.

Ejemplo práctico de API Stream y Lambda.

Lambda.

Existen varias formas de implementar Lambda:
Primera forma:

Si nos planteamos ordenar una serie de elementos que tenemos en un arrayList de enteros lo podríamos hacer mediante el método sortde la interfaz List pero este método espera que le proporcionemos un Comparator.

List <Integer> lista = Arrays.asList (1,2,3,4,5,6,7,8,9,10);
lista.sort(new MayorAMenor());

Ese Comparator lo podríamos implementar en primera instancia en una clase que implementará esa interfaz:

 public class MayorAMenor implements Comparator <Integer>{
    public int compare (Integer o1, Integer o2) {
        return -(o1.compareTo(o2));
    }
}

Este método sobreesribiría el “orden natural” de los números de forma que:

  • Si el primer número es menor que el segundo, devuelve un vaor positivo.
  • Si son iguales devuelve cero.
  • Si el primer número es mayor que el segundo, devuelve un valor negativo.

Mandamos a imprimir con la siguiente línea de código:

lista.forEach((n) -> System.out.println(n));

La impresión se está haciendo con una expresión muy sencilla de Lambda donde recogemos cada elemento del array y se imprime.

Segunda forma:

Java permite el uso de clases anónimas para hacer este tipo de operaciones de la siguiente forma:

Si solamente vamos a ordenar los números de forma inversa para esta operación podríamos instanciar el comparador en el main. Sin embargo el meollo del método sigue siendo solamente la siguiente línea de código:

....
return -(o1.compareTo(o2));

Tercera forma:

Podemos utilizar expresiones Lambda con Eclipse, ya que nos proporciona un atajo para crear una expresión Lambda a partir de la instanciación de una clase anónima mediante la combinación de teclado: Ctrl+1. Esto nos permite directamente crearlo así:

lista.sort(o1,o2) -> -(o1.compareTo(o2));

Cuarta forma:

Podemos proporcionar nosotros esta ordenación infiriendo los tipos de datos. Esta es una de las tantas potencias de las expresiones Lambda:

//Sin inferir el tipo de dato
lista.sort((Integer n1, Intenger n2)-> - (n1.compareTo(n2)));

//Infieriendo el tipo de dato.
lista.sort((n1,n2)-> -(n1.compareTo(n2)));

API Stream.

Repasando, el API Stream es una api bastante potente que nos permite realizar varias operaciones, como por ejemplo:

Si tenemos una lista de enteros:

List<Integer> lista = Arrays.asList(1,2,3,4,5,6,7,8,9,10);

Podemos recorrer colecciones e imprimir todos los elementos de la lista:

lista
     .stream()
     .forEach((n)-> System.out.println(n));

Podemos realizar operaciones de filtrado como imprimir solo los mayores o iguales que 5:

lista
     .stream()
     .filter((x)-> x>=5)
     .forEach((n)-> System.out.println(n));

Podemos imprimir solo los mayores o iguales a 5 ordenados inversamente:

lista
     .stream()
     .filter((x)-> x>=5)
     .sorted((n1,n2)-> -(n1.compareTo(n2)));
     .forEach((n)-> System.out.println(n));

También podemos sumar todos los elementos mayores o iguales a 5:

int resultado = lista
                     .stream()
                     .mapToInt(v-> v.intValue()) //Pasarlo de array a entero
                     .filter((x)-> x>=5)
                     .sum();
System.put.println(resultado);

Si quieres conocer mas sobre expresiones Lambda y API Stream te recomendamos que revises nuestros cursos de Java 8 de nuestra plataforma.

descarga-guia-eclipse