Expressions Lambda Java
Les expressions Lambda, également appelées fermetures, sont la nouvelle fonctionnalité la plus importante qui a motivé la sortie de Java 8.
Lambda permet de passer une fonction en paramètre à une méthode (les fonctions sont transmises aux méthodes en tant qu'arguments).
L'utilisation d'expressions Lambda peut rendre le code plus concis et compact.
Syntaxe
Le format de syntaxe d'une expression lambda est le suivant :
parametersest la liste des paramètres,expressionou{ statements; }est le corps de l'expression Lambda. S'il n'y a qu'un seul paramètre, les parenthèses peuvent être omises ; s'il n'y a aucun paramètre, des parenthèses vides sont toujours nécessaires.
Voici un exemple simple montrant l'utilisation d'une expression Lambda pour calculer la somme de deux nombres :
Exemple
MathOperation addition = (a, b) -> a + b;
// Appel de l'expression Lambda
int result = addition.operation(5, 3);
System.out.println("5 + 3 = " + result);
Dans l'exemple ci-dessus, MathOperation est une interface fonctionnelle qui contient une méthode abstraite operation. L'expression Lambda(a, b) -> a + bimplémente cette méthode abstraite, représentant l'opération d'addition des deux paramètres.
Les expressions Lambda peuvent être utilisées dans divers scénarios, notamment les opérations sur les collections, la gestion des événements, etc. Voici un exemple d'utilisation d'une expression Lambda pour parcourir une liste :
Exemple
// Utilisation d'une expression Lambda pour parcourir une liste
names.forEach(name -> System.out.println(name));
Les expressions Lambda introduisent un style de programmation plus fonctionnel en Java, rendant le code plus concis et lisible. Elles constituent une amélioration importante de la programmation fonctionnelle dans Java 8.
Fonctionnalités importantes
Concision
Les expressions Lambda offrent une syntaxe plus concise, particulièrement adaptée aux interfaces fonctionnelles. Comparées aux classes internes anonymes traditionnelles, les expressions Lambda rendent le code plus compact et réduisent le code répétitif.
Exemple
Runnable runnable1 = new Runnable() {
@Override
public void run() {
System.out.println("Hello World!");
}
};
// Utilisation d'une expression Lambda
Runnable runnable2 = () -> System.out.println("Hello World!");
Prise en charge de la programmation fonctionnelle
Les expressions Lambda sont une manifestation de la programmation fonctionnelle. Elles permettent de passer des fonctions comme arguments à des méthodes ou de les renvoyer comme valeurs de retour. Cette prise en charge rend Java plus flexible en programmation fonctionnelle, permettant de mieux gérer des tâches telles que les opérations sur les collections et le calcul parallèle.
Exemple
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(name -> System.out.println(name));
Capture de variable
Les expressions lambda peuvent accéder aux variables de la portée externe. Cette fonctionnalité est appelée capture de variable. Les expressions lambda peuvent capturer implicitement des variables locales qui sont final ou effectivement finales.
Exemple
int x = 10;
MyFunction myFunction = y -> System.out.println(x + y);
myFunction.doSomething(5); // Sortie 15
Références de méthodes
Les expressions lambda peuvent être encore simplifiées grâce aux références de méthodes. Les références de méthodes vous permettent de référencer directement des méthodes de classes ou d'objets existants sans écrire de code redondant.
Exemple
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(System.out::println);
Parallélisme
Les expressions lambda facilitent la mise en œuvre d'opérations parallèles. En utilisant l'API Stream combinée aux expressions lambda, le calcul parallèle peut être mis en œuvre plus facilement, ce qui améliore les performances du programme.
Exemple
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.parallelStream().mapToInt(Integer::intValue).sum();
L'introduction des expressions Lambda rend la programmation Java plus flexible et concise, et favorise le développement de la programmation fonctionnelle.
Exemples d'expressions Lambda
Exemples simples d'expressions 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)
Entrez le code suivant dans le fichier Java8Tester.java :
Fichier Java8Tester.java
Exécutez le script ci-dessus et la sortie est :
$ javac Java8Tester.java $ java Java8Tester 10 + 5 = 15 10 - 5 = 5 10 x 5 = 50 10 / 5 = 2 Hello Example Hello Google
Il convient de noter les deux points suivants lors de l'utilisation des expressions Lambda :
-
Les expressions Lambda sont principalement utilisées pour définir des interfaces de type méthode pour une exécution en ligne (par exemple, une interface de méthode simple). Dans l'exemple ci-dessus, nous avons utilisé différents types d'expressions Lambda pour définir les méthodes de l'interface MathOperation, puis nous avons défini l'exécution de operation.
-
Les expressions Lambda éliminent les tracas liés à l'utilisation de méthodes anonymes et donnent à Java des capacités de programmation fonctionnelle simples mais puissantes.
Portée des variables
Les expressions lambda ne peuvent référencer que des variables locales externes marquées comme final. C'est-à-dire que les variables locales définies en dehors de la portée de la lambda ne peuvent pas être modifiées à l'intérieur de la lambda ; sinon, une erreur de compilation se produira.
Entrez le code suivant dans le fichier Java8Tester.java :
Fichier Java8Tester.java
Exécutez le script ci-dessus et la sortie est :
$ javac Java8Tester.java $ java Java8Tester Hello! Example
Nous pouvons également accéder directement aux variables locales externes dans l'expression lambda :
Fichier Java8Tester.java
Les variables locales dans les 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 une sémantique de final).
int num = 1; Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num)); s.convert(2); num = 5; //报错信息:Local variable num defined in an enclosing scope must be final or effectively final
Il n'est pas permis de déclarer un paramètre ou une variable locale avec le même nom qu'une variable locale à l'intérieur d'une expression Lambda.
String first = ""; Comparator<String> comparator = (first, second) -> Integer.compare(first.length(), second.length()); //编译会出错
Autres extensions
Nouveautés de Java 8