Expressions Lambda amb Java 8

Entre les múltiples novetats que ens brinda Java 8 trobem les expressions lambda.
En aquest tutorial veurem en què consisteixen, quins tipus existeixen, com crear-les i com utilitzar-les.

Índex de continguts

  • 1. Introducció
  • 2. Entorn
  • 3. Tipus
    • 3.1. Consumidors
    • 3.2. Proveïdors
    • 3.3. Funcions
      • 3.3.1. Operadors unaris
      • 3.3.2. Opreadores Binaris
    • 3.4. Predicats
  • 4. Referència a mètodes
  • 5. Ús
  • 6. Conclusions
  • 7. Referències

Introducció

Les expressions lambda són funcions anònimes, és a dir, funcions que no necessiten una classe.
la seva sintaxi bàsica es detalla a continuació:

sintaxi

  1. l’operador lambda (- >) separa la declaració de paràmetres de la declaració de el cos de la funció.
  2. paràmetres:
    • Quan es té un sol paràmetre no cal utilitzar els parèntesis.
    • Quan no es tenen paràmetres , o quan es tenen dos o més, cal utilitzar parèntesis.
  3. cos de lambda:
    • quan el cos de l’expressió lambda té una única línia no cal utilitzar les claus i no necessiten especificar la clàusula return en el cas que hagin de tornar valors.
    • Quan el cos de l’expressió lambda té més d’una línia es fa necessari utilitzar les claus i cal incloure la clàusula return en el cas que la funció hagi de retornar un valor.

Alguns exemples d’expressions lambda poden ser:

  • z – > z + 2
  • () – > System.out.println (” Missatge 1 “)
  • ( int longitud, int alçada) – > {return alçada * longitud; }
  • (String x) – > {a String retorn = x; a retorn = retorno.concat ( “***”);
    return retorn; a}

Com hem vist les expressions lambda són funcions anònimes i poden ser utilitzades allà on el tipus acceptat sigui una interfície funcional però … què és una interfície funcional?
Una interfície funcional és una interfície amb un i només un mètode abstracte. La declaració és exactament igual que les interfícies normals amb dues característiques addicionals:

  • Té un únic mètode abstracte, com ja hem dit.
  • De manera opcional pot estar anotada com @ FunctionalInterface.

El motiu de que la interfície tingui un únic mètode abstracte és que serà l’expressió lambda la qual proveirà de la implementació per a aquest mètode.

A continuació alguns exemples d’interfície funcional:

Java

1
2
3
4

@FunctionalInterface
public interface runnable {
public abstract void run ();
}

Java

1
2
3
4
5
6

public interface MiInterfaz {
default void saluda () {
System.out.println ( “Una salutació!”);
}
public abstract int calcula (int dato1, int dada2);
}

Java

1
2
3
4
5
6
7

@FunctionalInterface
public interface Comparator {
/ / Es eludeixen els mètodes default i estàtics
int compari (T o1, T o2);
// El mètode equals (Object obj) és implícitament implementat per la classe objecte.
boolean equals (Object obj);
}

Entorn

el tutorial està escrit usant el següent entorn:

  • Maquinari: MacBook Pro 17 ‘(2.66 GHz Intel Core i7, 8GB DDR3 SDRAM).
  • Sistema operatiu: Mac OS X Lion 10.10.3.
  • NVIDIA GeForce GT 330M 512Mb.
  • Crucial MX100 SSD 512 Gb.

Tipus

Les expressions lambda pot classificar de la següent manera:

  • Consumidors.
  • Proveïdors.
  • Funcions.
    • Operadors unaris.
    • Operadors Binaris.
  • Predicats.

a continuació anirem detallant un a un i explicant en què consisteixen.

3.1. Consumidors

Es tracta d’aquelles expressions lambda que accepten un sol valor i no tornen cap valor.

Java

1

String message – > System.out.println (message);

Les expressions BiConsumidoras, un cas especial de les expressions consumidores , són aquelles que prenen dos valors com a paràmetre i no tornen resultat.

Java

1

(String key, String value) – > System.out.println ( “Key:% s, value:% s% n”, key, value);

3.2. Proveïdors

En aquest cas es tracta d’expressions que no tenen paràmetres però tornen un resultat.

Java

1

() – > return createRandomInteger ()

3.3. Funcions

Aquelles expressions que accepten un argument i retornen un valor com a resultat i els tipus no tenen perquè ser iguals.

Java

1

Order persistedOrder – > persistedOrder.getIdientifier ();

Les BiFunciones són aquelles expressions de tipus funció que accepten 02:00 arguments i retornen un resultat.

Java

1

(Address address , String name) – > new Person (name, address);

3.3.1 Operadors unaris

Cas especial de funcions en les que tant el paràmetre com el valor retornat són de la mateixa mena.

Java

1

String message – > message.toLowerCase ()

3.3.2 Operadors Binaris

Igual que en el cas dels operadors unaris, es tracta d’un cas especial de funcions en què els dos arguments i el resultat són de la mateixa mena.

Java

1

(String message, String anotherMesssage) – > message.concat (anotherMessage);

3.4. Predicats

Es tracta d’expressions que accepten un paràmetre i retornen un valor lògic.

Java

1

String message – > message.length > 50

Com en els casos anteriors, es poden tenir BiPredicados, predicats que en lloc de tenir un paràmetre, tenen dos.

Java

1

(path, attr) – > String.valueOf (path) .endsWith ( “. js”) && attr.size () > 1024

referències a mètodes

Les referències als mètodes ens permeten reutilitzar un mètode com a expressió lambda. Per fer ús de les referències a mètodes només cal utilitzar la següent sintaxi: referenciaObjetivo :: nombreDelMetodo.

Java

1

File :: canRead // en lloc de File f – > f.canRead ();

Amb les referències als mètodes s’ofereix una anotació més ràpida per expressions lambda simples i existeixen 3 tipus diferents:

  • Mètodes estàtics.
  • Mètodes d’instància d’un tipus.
  • Mètodes d’instància d’un objecte existent.

Exemple d’ús amb mètode estàtic:

Java

1
2

(String info) – > System.out.println (info) // Expressió lambda sense referències.
System.out :: println // Expressió lambda amb referència a mètode estàtic.

Exemple d’ús amb mètode d’un tipus:

Java

1
2

(Student Student , int registryIndex) – > student.getRegistry (registryIndex) // Expressió lambda sense referències.
Student :: getRegistry // Expressió lambda amb referència a mètode d’un tipus.

Exemple d’ús amb mètode d’un objecte existent:

Java

1
2

Student student – > getMarks (student) // Expressió lambda sense referències.
this :: getMarks // Expressió lambda amb referència a mètode d’un objecte existent.

Ús

Com hem vist amb anterioritat, les lambdes poden ser utilitzades allà on el tipus de paràmetres acceptats sigui una interfície funcional. Aquest és el cas de moltes de les funcionalitats que ofereix java.util.stream, nou Api que apareix amb Java 8, que permet la programació funcional sobre un flux de valors sense estructura.

Vegem alguns exemples:

Exemple 1:

Java

1
2
3
4
5

List aList = …
aList.stream ()
.findFirst (element – > element.getValue () == VALUE_TO_COMPARE)
.ifPresent (System.out :: println);

Mitjançant el codi anterior fem ús de lambdes per:

  • element – > element.getValue == VALUE_TO_COMPARE: atorguem un predicat a la funció findFirst de l’API Stream, aquesta funció utilitzarà el predicat per tornar un Optional (una altra de les novetats de Java 8 que ja va tractar Daniel Díaz en la seva tutorial Jugant amb la classe Optional en Java agost.) Amb el Primer Valor que corresponen a la expressió lambda.
  • System.Out :: Println: Establecemos Un Consumidor para la Funció Ifpreent, de la clase opcional, que en cas caso de exigir el valor, ejecutará la expressió lambda .

ejemplo 2:

java

1
2
3
4
5
6

mapa<

cadena, sencer > mapa = nou treemap <> ();

mapa.
map.foreach ((lletra, nombre) – > stringbuilder.append (lletra.concat (cadena.Valueof (nombre))))));
System.out.println (StringBuilder.Tostring ());

en el anterior còdigo utilitzadores una lambda para procesar valores, Un Través de l’ONU Consumidor, que concatena Los Valores Enteros Que Se Obtienen del Mapa.

Ejemplo 3:

java

1
2
3
4
5
6
7

proveu (lector de búferedReades = fitxers.newBufferedReader (sici.get (“somelines.txt”), standardcharsets.utf_8)) {
lector .lines ()
.flatmap (línia – > Stream.of (línia.split (word_regexp))
.distint ( )
.map (cadena :: tolowcase)
.foreach (System.out :: println);
}

El código anterior Toma Un Fichero, Recorre Sus Líneas, Mapea Los Valores Obtenidos de Cada Linea que corresponden amb la Expresió de Word_regexp regular, Filtra Aquellos Que Sean Distintos, Los Pasa a Minúscules i Los Imprime por Pantalla Uno A uno.

  • Línia – > Stream.of (línia.Split (word_regexp)): Develve un Stream amb els Valores Obtenidos d’Aplicar La Divisió de la Línea Mediante la Expressió Regular. El Método FlatMap Irá recogiogendo Los Streams Generos d’Esta Manera i Los Convertirá a Un Único Rierol Que Podrá Ser procesado con posterioridad.
  • cadena :: tolowcase: transforma los cordes del rierol a minúscules.
  • LI> System.Out :: PrintLN: Ya Lo vimos con anterioridad, muestra por String String.

Conclusions

Las expressiones lambda de java 8 nos ofrecen varias mejoras amb respecte a les versions anteriores:

  • nos acerca a la programación funcional.
  • Hace nuestro código más preciso i llegible, mejorando, en consecuència, su madenibilidad.
  • su utilització junto con la api Stream cau a Más Fácil la ejecución concurrente de tareas.

en este tutorial hemos mostrat en qué consisteixen i qué tipos fenc, cuándo pueden utilització i les diferents MANERAS DE UTILIZARLAS. Pendiente de posteriors tutoriales Queda Tratar Aspectos Más Avanzados Como Corrents Finitos E Infinitos, utilització de colectores o Depuració de rierols i expressiones lambda.

Referències

  • jdk 8 mooc: lambdas i fluxos Introducció
  • Oracle Lambda Expressions Documentació

SI QUIERES Profundizar en Esta i en El Resto de Novedades Que Incuye Java 8, Recuerda que Ahora Puedes Asistir A Los Cursos Públics de “Novedades de Java 8”, Donde Te Levaremos de la Mano Para Experimentar y Aprender A Sacar Todo El Partit de Todos Los Cambios delguaje. Así Estarás al Día. PUEDES COMPROBAR LAS PROXIMAS CONVOCATORIAS DEL CURSO “NOVEDADES JAVA 8”

Deixa un comentari

L'adreça electrònica no es publicarà. Els camps necessaris estan marcats amb *