English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Tutorial Básico de Java

Controle de fluxo Java

Java Array

Java Orientação a Objetos (I)

Java Orientação a Objetos (II)

Java Orientação a Objetos (III)

Tratamento de Exceção Java

Java Lista (List)

Java Queue (fila)

conjunto Java Map

conjunto Java Set

Java Entrada e Saída (I/O)

Reader do Java/Writer

outros tópicos do Java

Expressões Lambda Java

Java 8 Novas funcionalidades

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.

Sintaxe

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 de expressão lambda

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.

Escopo de variáveis

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

Java 8 Novas funcionalidades