Blog ENI : Toute la veille numérique !
-25€ dès 75€ sur les livres en ligne, vidéos... avec le code FUSEE25. J'en profite !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Java
  3. Les expressions lambda
Extrait - Java Les fondamentaux du langage (avec exercices pratiques et corrigés)
Extraits du livre
Java Les fondamentaux du langage (avec exercices pratiques et corrigés)
3 avis
Revenir à la page d'achat du livre

Les expressions lambda

Introduction

Les expressions lambda ont été longuement attendues dans l’écosystème Java. Elles sont apparues avec Java 8. Java a ainsi rattrapé son retard sur certains langages concurrents comme le C#. Mais que sont les expressions lambda ? Ce sont tout simplement des fonctions que l’on peut passer en paramètre d’une autre fonction. Cela permet de simplifier le code dans certaines situations là où le développement objet offre des solutions verbeuses à base de classes anonymes notamment.

Fonctionnement

1. Les interfaces fonctionnelles

Le fonctionnement des expressions lambda s’appuie sur le fonctionnement des interfaces. En effet, un paramètre de méthode attendant une expression lambda est tout simplement un paramètre du type d’une interface. Cette interface doit cependant respecter une règle importante : elle ne doit définir la signature que d’une seule méthode abstraite.

Dans ce cas de figure, l’interface devient une interface fonctionnelle. Il est toujours possible d’avoir des méthodes complémentaires si elles ne sont pas abstraites (méthodes par défaut, méthodes statiques).

Pour exemple, voici le code simplifié de l’interface java.util.Comparator<T>. Son rôle est de proposer un mécanisme de comparaison d’objets d’un même type :

@FunctionalInterface 
public interface Comparator<T> {  
   int compare(T o1, T o2);  
  ...     
} 

Une interface fonctionnelle est une interface comme les autres dans sa structure. La différence est la présence de l’annotation @FunctionalInterface qui est d’ailleurs optionnelle, mais qui permet au compilateur de faire les vérifications de cohérence nécessaire. Tant que vous n’avez pas exactement une et une seule méthode abstraite dans l’interface, le compilateur indiquera le message suivant :

images/04RI01.png

Java propose un ensemble d’interfaces fonctionnelles répondant à la grande majorité des situations. Il ne sera donc pas forcément fréquent d’en créer soi-même. Elles sont disponibles dans le package java.util.function. Une section dédiée permettra d’explorer le contenu de ce package.

Un exemple concret d’utilisation des interfaces fonctionnelles est la méthode sort de l’interface List<T>. Cette méthode permet de trier les éléments de la liste selon un critère de comparaison fourni en paramètre de la méthode sous la forme d’une implémentation de l’interface Comparator<T> qui, je le rappelle, permet de comparer deux objets du même type.

Voici la signature de la méthode sort :

void java.util.List.sort(Comparator<? super String> c) 

La méthode...

Manipulation des collections

1. L’API Stream

L’émergence des expressions lambda a permis la création ou l’enrichissement d’un certain nombre d’API. La plus caractéristique est l’API Stream permettant la manipulation de flux d’éléments. Cette API permet de simplifier la manipulation des collections. Le développeur se concentre sur les opérations à réaliser sans se préoccuper de la manière de parcourir la collection.

Cette section a pour objectif de présenter le fonctionnement de cette API afin d’être autonome à l’issue de ce chapitre.

2. Théorie

Généralement, les collections sont utilisées pour stocker des informations afin de pouvoir les récupérer ou effectuer des traitements dessus. La technique classique pour réaliser des opérations sur les éléments contenus dans une collection consiste à faire une boucle for ou à utiliser l’itérateur associé à la collection. Cette solution peut être avantageusement remplacée par l’utilisation de streams et de pipelines. Pour illustrer le fonctionnement de ces deux éléments, on peut faire la correspondance avec le fonctionnement d’une usine.

Notre usine reçoit la matière première, laquelle traverse différentes unités de transformation pour obtenir en sortie le produit fini. Dans notre cas, les données présentes dans la collection représentent la matière première. Celles-ci sont transportées par l’intermédiaire d’objets implémentant généralement l’interface Stream. Les unités de transformation sont représentées par les pipelines. Ceux-ci peuvent produire un résultat directement exploitable (le produit fini) ou un autre objet Stream qui va alimenter un nouveau pipeline.

Toutes les classes implémentant l’interface Collection sont capables de fournir un objet de type Stream. C’est cet objet qui est responsable de l’itération sur les éléments présents dans la collection.

Les pipelines sont un peu plus complexes puisqu’ils sont constitués de plusieurs éléments.

Le premier représente la source...

Conclusion

Ce chapitre vous a présenté la puissance des expressions lambdas et l’intérêt de quelques API qui gravitent autour. Bien sûr, ce n’est qu’un bref aperçu. Vous pourrez découvrir la richesse de ces API au fur et à mesure de vos besoins.