English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
L'espressione lambda, anche conosciuta come closure, è una delle nuove funzionalità più importanti introdotte con Java 8.
La lambda permette di passare una funzione come parametro di un metodo (passare una funzione come parametro a un metodo).
L'uso delle espressioni lambda può rendere il codice più conciso e compatto.
La sintassi della espressione lambda è la seguente:
(parameters) -> expression o (parameters) -> { statements; }
Ecco le caratteristiche importanti delle espressioni lambda:
Dichiarazione di tipo opzionale:Non è necessario dichiarare il tipo dei parametri; il compilatore può riconoscere i valori dei parametri in modo uniforme.
Parentesi tonde opzionali per i parametri:Non è necessario definire parentesi tonde per un singolo parametro, ma sono necessarie per più parametri.
Parentesi graffate opzionali:Se il corpo contiene una sola istruzione, non è necessario utilizzare parentesi graffate.
Parola chiave di ritorno opzionale:Se il corpo dell'espressione contiene solo un'espressione, il compilatore restituirà automaticamente il valore; i parentesi graffati devono specificare chiaramente che l'espressione restituisce un valore numerico.
Esempio semplice di espressione lambda:
// 1. 不需要参数,返回值为 5 () -> 5 // 2. 接收一个参数(数字类型),返回其2倍的值 x -> 2 * x // 3. 接收2个参数(数字),并返回他们的差值 (x, y) -> x – y // 4. 接收2个int型整数,返回他们的和 (int x, int y) -> x + y // 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void) (String s) -> System.out.print(s)
Inserisci il seguente codice nel file Java8Tester.java:
public class Java8Tester { public static void main(String args[]){ Java8Tester tester = new Java8Tester(); // 类型声明 MathOperation addition = (int a, int b) -> a + b; // 不用类型声明 MathOperation subtraction = (a, b) -> a - b; // 大括号中的返回语句 MathOperation multiplication = (int a, int b) -> { return a * b; }; // 没有大括号及返回语句 MathOperation division = (int a, int b) -> a / b; System.out.println("10 + 5 = " + tester.operate(10, 5, addition)); System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction)); System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication)); System.out.println("10 / 5 = " + tester.operate(10, 5, division)); // 不使用括号 GreetingService greetService1 = message -> System.out.println("Hello " + message); // 使用括号 GreetingService greetService2 = (message) -> System.out.println("Hello " + message); greetService1.sayMessage("w3codebox"); greetService2.sayMessage("Google"); } interface MathOperation { int operation(int a, int b); } interface GreetingService { void sayMessage(String message); } private int operate(int a, int b, MathOperation mathOperation){ return mathOperation.operation(a, b); } }
Esegui lo script sopra, il risultato di output è:
$ javac Java8Tester.java $ java Java8Tester 10 + 5 = 15 10 - 5 = 5 10 x 5 = 50 10 / 5 = 2 Hello w3codebox Hello Google
Quando si utilizzano le espressioni lambda, è necessario notare due punti:
Le espressioni lambda vengono principalmente utilizzate per definire interfacce di tipo di metodo eseguito in loco, ad esempio, un'interfaccia di metodo semplice. Nei nostri esempi, abbiamo utilizzato vari tipi di espressioni lambda per definire i metodi dell'interfaccia MathOperation. Poi abbiamo definito l'esecuzione di sayMessage.
Le espressioni lambda evitano la complicazione dell'uso di metodi anonimi e offrono alla Java la capacità di programmazione funzionale semplice ma potente.
Le espressioni lambda possono solo referenziare variabili locali esterne marcate come final, il che significa che non possiamo modificare le variabili locali definite al di fuori del dominio all'interno della lambda, altrimenti si verifica un errore di compilazione.
Inserisci il seguente codice nel file Java8Tester.java:
public class Java8Tester { final static String salutation = "Hello! "; public static void main(String args[]){ GreetingService greetService1 = message -> System.out.println(salutation + message); greetService1.sayMessage("w3codebox"); } interface GreetingService { void sayMessage(String message); } }
Esegui lo script sopra, il risultato di output è:
$ javac Java8Tester.java $ java Java8Tester Hello! w3codebox
Possiamo anche accedere direttamente alle variabili locali esterne nell'espressione lambda:
public class Java8Tester { public static void main(String args[]) { final int num = 1; Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num)); s.convert(2); // Il risultato di output è 3 } public interface Converter<T1, T2> { void convert(int i); } }
Le variabili locali delle espressioni lambda non devono essere dichiarate come final, ma devono essere invariabili per il codice successivo (cioè hanno un significato implicito di final)
int num = 1; Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num)); s.convert(2); num = 5; // Messaggio di errore: La variabile locale num definita in uno scope esterno deve essere finale o effettivamente final
Non è permesso dichiarare un parametro o una variabile locale con lo stesso nome nell'espressione Lambda.
String first = ""; Comparator<String> comparator = (first, second) -> Integer.compare(first.length(), second.length()); // Errore di compilazione