English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
A expressão lambda, também conhecida como closure, é um dos principais motores do Java 8 a característica mais importante da versão lançada.
Lambda permite passar uma função como parâmetro de um método (função passada como parâmetro para um método).
O uso da expressão lambda pode tornar o código mais conciso e compacto.
O formato da sintaxe da expressão lambda é o seguinte:
(parâmetros) -> expressão ou (parâmetros) -{ estatements; }
Aqui estão as principais características da expressão lambda:
Declaração de tipo opcional:Não é necessário declarar o tipo do parâmetro, o compilador pode identificar uniformemente o valor do parâmetro.
Parênteses de parâmetros opcionais:Um parâmetro não precisa de definição de parênteses, mas vários parâmetros precisam de definição de parênteses.
Chaves opcionais:Se o corpo da expressão lambda contiver uma instrução, não é necessário usar chaves.
Palavra-chave de retorno opcional:Se o corpo da expressão lambda tiver apenas uma expressão, o compilador retornará automaticamente o valor, e os colchetes precisam especificar claramente que a expressão retorna um valor numérico.
Exemplo simples de expressão lambda:
// 1. não precisa de parâmetros, o valor retornado é 5 () -> 5 // 2. aceita um parâmetro (tipo numérico), e retorna seu2o valor multiplicado x -> 2 * x // 3. aceita2um parâmetro (número), e retorna a diferença deles (x, y) -> x - y // 4. aceita2um inteiro int, retorna a soma deles (int x, int y) -> x + y // 5. aceita um objeto string e imprime na console, sem retornar nenhum valor (parece que retorna void) (String s) -> System.out.print(s)
No Java8Inserir o seguinte código no arquivo Tester.java:
public class Java8Tester { public static void main(String args[]){ Java8Tester tester = new Java8Tester(); // declaração de tipo MathOperation adição = (int a, int b) -> a + b; // sem declaração de tipo MathOperation subtração = (a, b) -> a - b; // instrução de retorno dentro das chaves MathOperation multiplicação = (int a, int b) -> { return a * b; }; // sem chaves e instrução de retorno MathOperation divisão = (int a, int b) -> a / b; System.out.println("10 + 5 = " + tester.operate(10, 5, adição)); System.out.println("10 - 5 = " + tester.operate(10, 5, subtração)); System.out.println("10 x 5 = " + tester.operate(10, 5, multiplicação)); System.out.println("10 / 5 = " + tester.operate(10, 5, divisão)); // não usar parênteses GreetingService greetService1 = message -> System.out.println("Hello " + message); // usar parênteses 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); } }
Executar o script acima, o resultado da saída é:
$ javac Java8Tester.java $ java Java8Tester 10 + 5 = 15 10 - 5 = 5 10 x 5 = 50 10 / 5 = 2 Hello w3codebox Hello Google
Ao usar expressões lambda, é importante considerar os seguintes dois pontos:
As expressões lambda são principalmente usadas para definir tipos de interfaces de métodos executados em linha, por exemplo, uma interface de método simples. No exemplo acima, usamos vários tipos de expressões lambda para definir o método da interface MathOperation. Em seguida, definimos a execução de sayMessage.
As expressões lambda eliminam a complexidade de usar métodos anônimos e oferecem à Java a capacidade de programação funcional simples mas poderosa.
As expressões lambda podem apenas referenciar variáveis locais marcadas como final no escopo externo, o que significa que não podemos modificar as variáveis locais definidas fora do escopo dentro da expressão lambda, caso contrário, ocorrerá um erro de compilação.
No Java8Inserir o seguinte código no arquivo Tester.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); } }
Executar o script acima, o resultado da saída é:
$ javac Java8Tester.java $ java Java8Tester Hello! w3codebox
Também podemos acessar diretamente as variáveis locais externas nas expressões 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); // O resultado da saída é 3 } public interface Converter<T1, T2> { void convert(int i); } }
As variáveis locais de expressões lambda não precisam ser declaradas como final, mas devem ser inalteráveis por parte do código subsequente (ou seja, têm o significado implícito de final)
int num = 1; Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num)); s.convert(2); num = 5; //Mensagem de erro: A variável local num definida em um escopo encerrado deve ser final ou efetivamente final
Não é permitido declarar um parâmetro ou uma variável local com o mesmo nome dentro de uma expressão Lambda.
String first = ""; Comparator<String> comparator = (first, second) -> Integer.compare(first.length(), second.length()); //O compilação dará erro