[vc_row][vc_column][vc_column_text]
Expresiones Lambda en Java
Para empezar, las expresiones Lambda son funciones escritas en Java que son utilizadas en los métodos como parámetros del tipo objectos. Al principio, solíamos definir funciones en Java solo en métodos, pero ahora podemos usarlas dentro de cuerpos de métodos.[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
Interfaces Funcionales
Se puede utilizar una expresión lambda donde utilicemos una Interface Funcional. Las Interfaces Funcionales en Java son aquellas interfaces que solo tienen un método declarado y ser implementado, como las interfaces Runnable o Comparator.
Cuando cambiemos el código de la forma tradicional de codificación para utilizar Lambdas, siempre debemos seguir algunos pasos importantes.[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
Pasos para utilizar Expresiones Lambda:
Paso 1: En el código Java que tenga escrito, elimine las declaraciones y escriba los nombres de referencia. Por lo tanto, cambie algo como esto:
1 2 3 4 5 6 | Collections.sort(pList, new Comparator() { @Override public int compare(Person p1, Person p2) { // TODO Auto-generated method stub return p1.getName().compareTo(p2.getName()); } }); |
A algo como esto:
1 2 3 | Collections.sort(pList, (p1, p2) { return p1.getName().compareTo(p2.getName()); }); |
Paso 2: Elimine los paréntesis, agregue el símbolo de lambda -> y elimine la palabra return:
1 | Collections.sort(pList, (p1, p2) -> p1.getName().compareTo(p2.getName()); |
Las expresiones Lambda solo se refieren al cuerpo de la función, NO con el nombre de la función.
También podemos usar expresiones Lambda donde quiera que hayamos utilizado funciones anónimas. Podemos usarlo también en una nueva clase Thread (aquí, se esta utilizando en lugar de una interface Runnable).
1 | new Thread(() -> System.out.println("Run the thread")); |
Además, en Java 8, se realizaron cambios en algunas interfaces para introducir métodos que admitan expresiones lambda. Por ejemplo:
- Collections.sort(lambda)
- List.sort(lambda)
- Iterable.forEach(lambda)
- List.replaceAll(lambda)
- Collections.removeIf(lambda)
Estos métodos fueron creados en Java 8 con la introducción de algunos otros conceptos.[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
Métodos Default
Los métodos Default fueron introducidos en las interfaces en Java 8 conde la implementación por defecto es proporcionada. Cualquier clase que implemente la interface que no proporcione una implementación, utiliza el método Default.
Podemos utilizar las expresiones lambda en un bucle for de la siguiente forma:
1 2 3 4 5 | for(Person s:pList){ System.out.println(s.getName()); } // con lambdas, podemos reescribir el código como indica list.forEach(p -> System.out.println(p.getName()); |
El uso de las expresiones lambda en los bucles for significará que son iteradores internos, ya que hay una llamada al método que será uniforme para todos los elementos de la lista.
Funciones de orden superior
También podemos volver a escribir expresiones lambda de una manera más adecuada:
1 2 3 | Collections.sort(pList, (p1, p2) -> p1.getName().compareTo(p2.getName()); // can be rewritten as pList.sort(Comparator.comparing(p -> p.getName())); |
Referencia e métodos utilizando referencia de acceso directo
1 | pList.sort(Comparator.comparing(Person :: getName)); |
Static Imports
También se pueden utilizar static imports para re escribir el código:
1 | pList.sort(comparing(Person :: getName)); |
Entonces, si comparamos el código tradicional y el código anterior, podemos ver cuánto código repetitivo se ha eliminado.
A continuación se muestra un ejemplo simple para usar las expresiones lambda.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | package com.corejava.practise; import java.util.Arrays; import java.util.Comparator; import java.util.List; public class Person { int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } String name; public Person(int age, String name) { super(); this.age = age; this.name = name; } @Override public String toString() { return ("Person Name:" + this.getName() + " ::Person Age: " + this.getAge()); } public static void main(String args[]) { Person[] personList = new Person[] { new Person(23, "Ravi"), new Person(23, "Anands"), new Person(32, "Suraj") }; List < Person > pList = ((List) Arrays.asList(personList)); System.out.println("UnSorted List is ::" + pList); // TODO SCENERIO 1: Elimine los comentarios para utilizar una clase Comparator personalizada // Collections.sort(pList, new PersonNameComparator() { // @Override // public int compare(Person p1, Person p2) { // // TODO Auto-generated method stub // return p1.getName().compareTo(p2.getName()); // } // }); // TODO SCENERIO 2:: Elimine los comentarios para tratar de utilizar una clase anónima de Comparator //Inner class .. Functional Interface // Collections.sort(pList, new Comparator() { // @Override // public int compare(Person p1, Person p2) { // // TODO Auto-generated method stub // return p1.getName().compareTo(p2.getName()); // } // }); // TODO SCENERIO 3: Elimine los comentarios intentando utilizar una expresión lambda //using default methods //pList.sort((p1,p2) -> p1.getName().compareTo(p2.getName())); // TODO SCENERIO 4: Elimine los comentarios intentando utilizar una expresión lambda //using higher order functions //pList.sort(Comparator.comparing(p -> p.getName())); // TODO SCENERIO 5: Elimine los comentarios intentando utilizar una expresión lambda //using method references //pList.sort(Comparator.comparing(Person::getName)); //System.out.println("\nsSorted List is ::" + pList); } } |
[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
Este artículo esta basado en Don’t Fear the Lambda[/vc_column_text][/vc_column][/vc_row]