Comprendre les expressions lambdas en Java

Dans cet article on verra ce qu’est une expression lambda et comment elles fonctionnent.

Comprendre les expressions lambdas en Java

Published by: Stephane, Last edited

Les expressions lambdas apparaissent en Java avec la programmation fonctionnelle introduite sous Java 8. Une expression lambda est une fonction anonyme qui est passée comme paramètre d’une méthode. Cette expression lambda ou fonction anonyme peut accepter ou pas des paramètres en entrée et peut où pas retourner un résultat.

Exemple d’expression lambda

Runnable run = ()-> System.out.println("Hello World");

Les expressions lambdas comportent deux parties, les paramètres et le corps.

A. Les paramètres

Aucun paramètre :

()->System.out.println("Hello World")

Lorsque l’expression n’accepte aucun paramètre on utilise les parenthèses sans rien ajouter à l'intérieur.

Préciser ou non le type des paramètres :

(String nom, int age)->{}
(nom, age)->{}

On peut préciser ou non le type des paramètres. Il est toutefois à noter que si le type de l’un des paramètres est précisé alors le type de tous les autres paramètres devra l’être aussi. Ainsi l'expression lambda suivante est incorrecte

(String nom, age)->{}

Ignorer les parenthèses :

non ->{}

Si notre expression lambda n’accepte qu’un seul paramètre il est possible d’ignorer la parenthèse à condition d’ignorer le type du paramètre également. Les expressions suivantes sont donc incorrectes

String nom ->{} // le type doit être ignoré
nom, age ->{} // avec plus d’un paramètre on doit utiliser les parenthèses

B. Le corps

Dans le corps de l’expression lambda on peut écrire le code comme on le ferait normalement pour une méthode. Celui-ci peut ainsi retourner ou non un résultat. Exemple

nom ->{ return nom.toUpperCase();} // retourne le nom en caractère majuscule
nom ->{ System.out.println(nom);} // imprime le nom à la console

Lorsqu’une expression lambda retourne quelque chose il est possible d’ignorer les accolades {} ainsi que le mot clé return. Ceci ne sera possible qu'à la seule condition que l’expression ne contient qu’une seule opération. Remarquons aussi que nous avons ignoré le “;” à la fin de l’expression.

nom -> nom.toUpperCase()

Il en va de soit donc que les expressions suivantes sont incorrectes:

nom -> return nom.toUpperCase()

Si on veut explicitement utiliser le mot clé return on doit également utiliser les {} et terminer l’expression par un “;”

nom -> nom.toUpperCase();

Si on ignore les {} et le mot clé return on doit également ignorer le “;”

nom ->{ return nom.toUpperCase()}

Si on utilise les {} et le mot clé return on doit également ajouter le “;”

C. Réassigner le contenu des paramètres

Il n’est pas autorisé d’assigner un nouveau contenu aux paramètres des expressions lambdas. C’est paramètres sont considérés comme effectivement finals et le compilateur retournera une erreur si nous le faisons. L’expression ci-dessous produira donc une erreur de compilation:

nom -> {
    nom = "John Doe";
    System.out.println(nom);
}

Conclusion

Les expressions lambdas sont très couramment utilisées pour implémenter les interfaces fonctionnelles que nous verrons prochainement. Les streams que nous avons vu dans un précédent article en font grandement usage. Par exemple on peut implémenter l’interface fonctionnelle Consumer (interface qui accepte un paramètre en entrée et ne retourne rien) comme suit:

Consumer consumer = nom -> {System.out.println(nom);};

La méthode forEach() des listes (List) par exemple a la signature suivante: forEach(Consumer consumer). Lorsqu’on veut imprimer le contenu d’une liste on peut le faire comme suit

List noms = Arrays.asList("John", "Doe", "Janes");
noms.forEach(nom -> {System.out.println(nom);});

Ou en plus court en faisant usage de l'inférence des méthodes

noms.forEach(System.out::println);

Find me on twitter or on

"Je puis tout par Christ qui me fortifie." Phil 4:13