Maison >Java >javaDidacticiel >Maîtriser les expressions Lambda en Java Un guide complet
Malgré les nombreuses nouvelles versions de Java publiées, Java 8 reste l'une des versions les plus largement adoptées en raison de ses fonctionnalités puissantes et transformatrices. Les expressions Lambda, introduites dans Java 8, sont particulièrement populaires car elles rendent Java plus concis et efficace en permettant une programmation fonctionnelle. Cette fonctionnalité permet aux développeurs de remplacer les classes internes anonymes et verbeuses par une syntaxe simplifiée, rendant le code plus lisible et plus maintenable.
Dans ce guide, nous découvrirons comment les expressions Lambda simplifient le code, améliorent le traitement des données dans les collections et permettent aux développeurs Java d'écrire des applications modernes et performantes.
À la base, une expression Lambda est un moyen de représenter une méthode abstraite unique d'une interface fonctionnelle dans une syntaxe beaucoup plus simple. Cette fonctionnalité s'aligne sur le concept de méthode abstraite unique (SAM), qui permet aux interfaces avec une seule méthode non implémentée d'être traitées comme compatibles Lambda.
Syntaxe Lambda :
Une expression Lambda se compose généralement de trois parties :
(parameters) -> expression (parameters) -> { statements; }
(int x, int y) -> x + y
(String message) -> System.out.println(message)
La syntaxe des expressions Lambda en Java est à la fois flexible et intuitive, permettant aux développeurs de choisir entre un format concis d'une seule ligne ou un bloc plus détaillé lorsque plusieurs lignes de code sont nécessaires.
Avant Java 8, l'implémentation d'interfaces comme Runnable ou Comparator nécessitait des classes internes anonymes. Les expressions Lambda rationalisent ce processus en remplaçant le code passe-partout par un style plus fonctionnel. Voici une comparaison de la façon dont une expression Lambda simplifie les tâches courantes :
Exemple 1 : Utilisation d'expressions Lambda avec Runnable
Envisagez une implémentation simple de Runnable. L’utilisation d’une classe interne anonyme ressemblerait à ceci :
Runnable r1 = new Runnable() { @Override public void run() { System.out.println("Hello world one!"); } };
Avec les expressions Lambda, ce code peut être simplifié en :
(parameters) -> expression (parameters) -> { statements; }
Java 8 introduit un ensemble d'interfaces fonctionnelles prédéfinies dans le package java.util.function. Ces interfaces, telles que Predicate, Function, Consumer et Supplier, constituent une base pour les expressions Lambda, permettant aux développeurs d'exploiter les principes de programmation fonctionnelle.
En utilisant ces interfaces avec les expressions Lambda, les développeurs Java peuvent effectuer des opérations non seulement concises mais également hautement réutilisables.
Pour voir les expressions Lambda en action, passons en revue quelques scénarios qui montrent comment elles peuvent remplacer la syntaxe détaillée, rationaliser les opérations courantes et améliorer la lisibilité.
L'interface Runnable en Java représente une tâche qui peut être exécutée par un thread. La classe doit définir une méthode sans argument appelée run. Voici comment une expression Lambda simplifie une implémentation Runnable.
Exécutable avec une classe interne anonyme :
(int x, int y) -> x + y
Exécutable avec l'expression Lambda :
(String message) -> System.out.println(message)
L'utilisation des expressions Lambda réduit cinq lignes de code à une seule, soulignant comment elles peuvent simplifier le code Java.
L'interface Comparator est souvent utilisée pour définir une logique de tri des collections. Avec les expressions Lambda, la définition de critères de tri personnalisés devient plus concise et intuitive.
Comparateur pour trier une liste de personnes par nom de famille :
Runnable r1 = new Runnable() { @Override public void run() { System.out.println("Hello world one!"); } };
Les expressions Lambda facilitent le basculement entre les ordres de tri en modifiant la logique de comparaison, par exemple pour l'ordre décroissant :
Runnable r2 = () -> System.out.println("Hello world two!");
Cette approche est particulièrement utile dans les applications qui nécessitent un tri dynamique, permettant aux développeurs d'échanger facilement des critères de tri en fonction des entrées de l'utilisateur ou d'autres conditions.
Dans la programmation GUI, les écouteurs d'événements sont couramment utilisés pour gérer les actions des utilisateurs. Traditionnellement, des classes internes anonymes étaient requises, ce qui entraînait un code long. Les expressions Lambda, cependant, offrent un moyen plus propre d'implémenter ces écouteurs.
ActionListener avec classe interne anonyme :
Runnable r1 = new Runnable() { @Override public void run() { System.out.println("Running with anonymous inner class"); } }; r1.run();
ActionListener avec expression Lambda :
(parameters) -> expression (parameters) -> { statements; }
Les expressions Lambda permettent aux développeurs d'implémenter directement ActionListener sur une seule ligne, améliorant ainsi la lisibilité et réduisant le code passe-partout.
Un scénario courant dans les applications logicielles consiste à filtrer les données en fonction de plusieurs critères. En Java, cela peut être géré efficacement en combinant des expressions Lambda avec l'interface Predicate, permettant un filtrage dynamique des collections.
Considérons une liste d'objets Personne, que nous souhaitons filtrer en fonction de différents critères, tels que l'âge et le sexe.
Définition d'une classe SearchCriteria basée sur un prédicat :
(int x, int y) -> x + y
La classe SearchCriteria encapsule les conditions courantes pour filtrer les listes, ce qui permet une flexibilité dans l'application de différents filtres à une seule collection.
Utilisation des critères de filtrage :
(String message) -> System.out.println(message)
Cette approche élimine le besoin de plusieurs boucles for, offrant ainsi une solution plus propre, réutilisable et plus maintenable.
L'API Stream de Java 8 révolutionne la façon dont les collections sont traitées, en particulier avec les expressions Lambda qui permettent un filtrage, une transformation et une agrégation efficaces des données. Les flux permettent un traitement paresseux, dans lequel les données sont traitées uniquement lorsque cela est nécessaire, améliorant ainsi les performances pour les grands ensembles de données.
La méthode forEach de l'API Stream fournit une alternative à la boucle for traditionnelle, permettant d'appliquer des expressions Lambda à chaque élément d'une collection. Voici un exemple qui parcourt une liste d’objets Person.
Runnable r1 = new Runnable() { @Override public void run() { System.out.println("Hello world one!"); } };
Utilisation des références de méthodes :
Dans les cas où une méthode existante peut être réutilisée, Java autorise les références de méthode, un raccourci qui améliore la lisibilité.
Runnable r2 = () -> System.out.println("Hello world two!");
L'API Stream permet d'enchaîner les opérations, permettant aux développeurs de filtrer, cartographier et collecter les résultats dans une seule instruction.
Exemple : Filtrage et collecte :
Runnable r1 = new Runnable() { @Override public void run() { System.out.println("Running with anonymous inner class"); } }; r1.run();
Ce code filtre uniquement les hommes âgés de 18 à 25 ans, en utilisant les critères définis dans la classe SearchCriteria.
Cartographie et Transformation avec map :
La méthode map transforme chaque élément d'une collection, par exemple en extrayant ou en modifiant des propriétés.
Runnable r2 = () -> System.out.println("Running with Lambda Expression"); r2.run();
Utilisation de la carte pour les calculs :
Les méthodes mapToInt et mapToDouble sont utiles pour les calculs numériques.
(parameters) -> expression (parameters) -> { statements; }
Les flux prennent en charge les opérations paresseuses et hâtives, les opérations paresseuses (telles que le filtre) ne s'appliquant qu'en cas de besoin. Cette paresse optimise les performances en traitant uniquement les éléments nécessaires.
Exemple d'évaluation paresseuse :
(int x, int y) -> x + y
Seules les personnes âgées de plus de 30 ans sont traitées et les noms de famille sont imprimés, démontrant un filtrage paresseux.
La méthode parallelStream de Java répartit les tâches sur plusieurs threads, offrant ainsi des gains de performances significatifs pour les grands ensembles de données.
Exemple de flux parallèle :
(String message) -> System.out.println(message)
Le traitement parallèle divise la charge de travail, ce qui accélère les opérations sur les collections pour les tâches gourmandes en calcul.
Étant donné que les flux sont intrinsèquement immuables, les résultats doivent être collectés pour les conserver. La méthode collect fournit un moyen d'agréger et de conserver les résultats d'une opération de flux.
Exemple :
Runnable r1 = new Runnable() { @Override public void run() { System.out.println("Hello world one!"); } };
Ici, les résultats filtrés sont stockés dans une liste pour un traitement ultérieur, permettant aux développeurs de gérer des flux de données complexes de manière structurée.
Les expressions Lambda de Java 8, associées à l'API Stream, représentent un changement majeur vers la programmation fonctionnelle, rendant le code plus concis, expressif et maintenable. En remplaçant les classes internes anonymes, en améliorant le traitement des collections et en prenant en charge les opérations parallèles, les expressions Lambda sont devenues la pierre angulaire de l'écriture d'applications Java modernes.
Toutes corrections ou ajouts à cet article sont les bienvenus.
Merci d'avoir lu !
Runnable r2 = () -> System.out.println("Hello world two!");
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!