Java 8 – Parte 2 – Sintassi delle espressioni lambda

Nell’articolo precedente abbiamo visto una piccola introduzione all’utilizzo delle espressioni lambda in Java 8. Prima di saltare la tana del bianconiglio e addentrarci  nel paradigma funzionale in Java 8, vediamo come è possibile scrivere un’espressione lambda.

Di seguito verranno presentati 6 diversi modi.

Sintassi standard 

String[] arr = {"dev", "2", "geek", "is", "a", "geek", "site"};
Arrays.sort(arr, (String m, String n) -> Integer.compare(m.length(), n.length()));
System.out.println(Arrays.toString(arr));

La sintaassi standard di un’espressione lambda si compone di:

  1. una lista di parametri formali, separati dalla virgola e racchiusa tra parantesi. In questo caso (String m, String n)
  2. operatore lambda o operatore freccia: ->
  3. un corpo costituito da una singola espressione o da un blocco di codice. Nell’esempio una singola espressione.

Tipo del parametro dedotto

Se il compilatore può dedurre il tipo del parametro dal contesto, allora può essere omesso.

Nel codice precedente, il tipo dei parametri n può essere dedotto come String ed in questo caso è possibile ometterlo.

String[] arr = { "dev", "2", "geek", "is", "a", "geek", "site" };
Arrays.sort(arr, (m, n) -> Integer.compare(m.length(), n.length()));
System.out.println(Arrays.toString(arr));

Espressione lambda con blocco di codice

Se l’espressione non può essere scritta in una sola riga, può essere racchiusa tra {}. In questo caso è necessario esplicitare un’espressione return.

String[] arr = { "dev", "2", "geek", "is", "a", "geek", "site" };
Arrays.sort(arr, (String m, String n) -> {
	if (m.length() > n.length())
		return -1;
	else
		return 0;
});
System.out.println(Arrays.toString(arr));

Parametro singolo con tipo dedotto

Le parentesi possono essere omesse se c’è un solo parametro e il suo tipo può essere sottinteso.

String[] arr = { "dev", "2", "geek", "is", "a", "geek", "site" };
Stream stream = Stream.of(arr);
stream.forEach(x -> System.out.println(x));

Method references

Il codice dell’esempio precedente può essere riscritto usando i method reference. Possiamo pensare i method reference come delle lambda expression che non sono anonime, ma che si riferiscono ad un specifico metodo di una determinata classe (o di una istanza). Ad esempio, String::valueOf o Integer::compare sono esempi di method reference per metodi statici.

Stream stream = Stream.of(arr);
stream.forEach(System.out::println);

Senza parametri

Se la funzione non prevede parametri le espressioni lambda possono ancora essere usate. Ecco un esempio:

() -> {for(int i=0; i<10; i++) doSomthing();}

Regole di scoping

É importante comprendere lo scoping delle variabili all'interno di una espressione lambda prima di utilizzarle. Come per le classi interne ed anonime, valgono le seguenti regole:

  • le variabili dichiarate nell'ambiente esterno sono visibili nell'istruzione che costituisce il corpo della espressione lambda
  • le variabili locali dell'ambiente esterno utilizzate nella espressione devono essere effettivamente final.

Differentemente da classi interne e anonime

  • non introduce un nuovo ambiente di scoping: non si può dichiarare una variabile con un nome già definito nel metodo in cui viene scritta.

Conclusioni

Adesso che sappiamo le regole per scrivere una espressione lambda, dobbiamo comprendere perché e quando usarle. Nel prossimo articolo vedremo degli esempi concreti di uso delle espressioni lambda.

Happy coding...

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *