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

Tutoriel de base Java

Java contrôle de flux

Java tableau

Java orienté objet (I)

Java orienté objet (II)

Java orienté objet (III)

Gestion des exceptions Java

Java List

Java Queue (file d'attente)

Java Map collection

Java Set collection

Java entrée/sortie (I/O)

Java Reader/Writer

d'autres sujets Java

Java Lambda expressions

Java 8 New features

Les expressions lambda, également appelées closures, sont ce qui pousse Java 8 la caractéristique la plus importante de la version publiée.

Lambda permet de passer une fonction en tant que paramètre d'une méthode (une fonction est passée en tant que paramètre à une méthode).

L'utilisation des expressions lambda rend le code plus concis et compact.

Grammaire

Le format grammatical des expressions lambda est le suivant :

(paramètres) -> expression
ou
(paramètres) -{ statements; }

Voici les caractéristiques importantes des expressions lambda:

  • 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。

  • 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。

  • 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。

  • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。

Lambda 表达式示例

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)

Dans Java8Fichier Tester.java, entrez le code suivant :

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);
   }
}

Exécuter le script suivant, le résultat de la sortie est :

$ javac Java8Tester.java 
$ java Java8Tester
10 + 5 = 15
10 - 5 = 5
10 x 5 = 50
10 / 5 = 2
Hello w3codebox
Hello Google

Il faut noter deux points lors de l'utilisation des expressions Lambda :

  • Les expressions lambda sont principalement utilisées pour définir des interfaces de méthodes exécutées en ligne, par exemple, une interface de méthode simple. Dans cet exemple, nous utilisons divers types d'expressions Lambda pour définir les méthodes de l'interface MathOperation. Ensuite, nous définissons l'exécution de sayMessage.

  • Les expressions lambda évitent les inconvénients des méthodes anonymes et fournissent à Java une capacité de programmation fonctionnelle simple mais puissante.

Portée des variables

Les expressions lambda ne peuvent引用非final variables externes, ce qui signifie qu'elles ne peuvent pas modifier les variables définies en dehors de leur domaine à l'intérieur de la lambda, sinon cela entraînera une erreur de compilation.

Dans Java8Fichier Tester.java, entrez le code suivant :

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);
   }
}

Exécuter le script suivant, le résultat de la sortie est :

$ javac Java8Tester.java 
$ java Java8Tester
Hello! w3codebox

Nous pouvons également accéder directement aux variables locales externes dans l'expression 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);  // Le résultat de la sortie est 3
    }
 
    public interface Converter<T1, T2> {
        void convert(int i);
    }
}

Les variables locales des expressions lambda n'ont pas besoin d'être déclarées comme final, mais elles ne doivent pas être modifiées par le code suivant (c'est-à-dire qu'elles ont implicitement le sens final)

int num = 1;  
Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num));
s.convert(2);
num = 5;  
//Error message: Local variable num defined in an enclosing scope must be final or effectively 
 final

It is not allowed to declare a parameter or local variable with the same name as a local variable in a Lambda expression.

String first = "";  
Comparator<String> comparator = (first, second); -> Integer.compare(first.length(), second.length());  //Compilation will fail

Java 8 New features