Chapitre 11 - Interfaces Fonctionnelles & Expressions Lambda
Chapitre 11 - Interfaces Fonctionnelles & Expressions Lambda
Chapitre 11 - Interfaces Fonctionnelles & Expressions Lambda
et Programmation Java
Chapitre 12 : Interfaces
fonctionnelles & Expressions
Lambda
Objectifs du chapitre
2
Interface fonctionnelle
3
Les interfaces fonctionnelles
Une interface fonctionnelle est une interface Java qui ne comporte qu'une seule
méthode abstraite, permettant de représenter un comportement ou une fonction
spécifique.
Elle peut également contenir des méthodes par défaut ou statiques, mais elle doit avoir
une et une seule méthode abstraite.
4
Les interfaces fonctionnelles
@FunctionalInterface //optionnel
interface Math1{
Si nous essayons de définir plus d'une seule méthode abstraite dans une interface
annotée avec @FunctionalInterface, le compilateur affichera une erreur.
Une interface fonctionnelle peut être instanciée à condition que vous fournissiez une
implémentation de sa méthode abstraite.
Elles offrent une flexibilité accrue pour personnaliser les comportements en fournissant
des implémentations de méthodes, éliminant ainsi la nécessité de créer plusieurs
classes qui implémentent l'interface.
7
Les interfaces fonctionnelles: instanciation
//méthode main
Math add = new Math() {
@Override
public int calculate(int x, int y) {
return x + y;
Objet anonyme
}
};
Un objet anonyme est une instance d'une interface/classe abstraite sans nom.
Les objets anonymes sont généralement utilisés dans des endroits où une classe complète
n'est pas nécessaire et où la création d'une classe dédiée peut sembler lourde.
L'instanciation d'une interface via un objet anonyme signifie qu’on peut créer plusieurs
implémentations de sa méthode abstraite sans avoir à créer une classe dédiée pour
chaque scénario spécifique. Cela simplifie considérablement le code en évitant la
surcharge de classes.
9
Lambda Expression
10
Expression Lambda
L’expression Lambda s’écrit d’une façon assez simple en suivant quelques règles:
Pour appliquer l’expression lambda, nous commencerons par la création d’un objet
anonyme.
public interface Math {
int calculate(int x, int y);
}
12
Expression Lambda : Comment implémenter ?
Le compilateur identifie l'interface à instancier à travers son type, donc il n'est pas
nécessaire de spécifier son nom.
13
Expression Lambda : Comment implémenter ?
Le compilateur reconnaît qu'il s'agit d'une interface avec une seule méthode abstraite,
ainsi que sa visibilité et son type de retour.
14
Expression Lambda : Comment implémenter ?
15
Expression Lambda : Comment implémenter ?
16
Expression Lambda : Comment implémenter ?
Résultat final:
17
Les interfaces fonctionnelles
prédéfinies
18
Les interfaces fonctionnelles prédéfinies
Interface
Description Argument(s) Type de retour Méthode abstraite
fonctionnelle
19
Les interfaces fonctionnelles prédéfinies
Interface
Description Argument(s) Type de retour Méthode abstraite
fonctionnelle
Transforme deux valeurs
BiFunction<T, U, R> de type T et U en une T, U R apply(T t, U u)
valeur de type R.
Function: Une interface fonctionnelle représentant une méthode qui prend un type
d'entrée et renvoie un type de sortie.
R apply(T t);
}
21
Interfaces fonctionnelles & Expression Lambda :
Appliquons (2/8)
Consumer: Une interface fonctionnelle représentant une action qui prend un type
d'entrée mais ne renvoie rien (void).
// Définition d'un “Consumer” qui prend un String et effectue une action (affichage)
Consumer<String> con = s -> System.out.println("Hello " + s);
// Application du “Predicate” avec "Hamdi" pour vérifier si elle commence par "n"
boolean check = pre.test("Hamdi"); //check = false
23
Interfaces fonctionnelles & Expression Lambda :
Appliquons (4/8)
Supplier: Une interface fonctionnelle représentant une fourniture qui ne prend aucun
argument et renvoie un type spécifié.
T get();
}
25
Interfaces fonctionnelles & Expression Lambda :
Appliquons (6/8)
R apply(T t, U u);
}
// Définition d'un “BiFunction” qui prend une chaîne (a) et un entier (b),
multiplie la longueur de la chaîne par l'entier, puis renvoie le résultat sous
forme de Float
BiFunction<String, Integer, Float> bif = (a, b) -> Float.valueOf(a.length() * b);
T apply(T t, T u);
}
27
Interfaces fonctionnelles & Expression Lambda :
Appliquons (8/8)
T apply(T t);
}
28
Les méthodes de référence
29
Les méthodes de référence
Les méthodes de référence sont un type particulier d'expressions lambda. Ils sont
souvent utilisés pour créer des expressions lambda simples en faisant référence à des
méthodes existantes. Leur utilisation est généralement associé avec “Stream”.
Il existe quatre types de références de méthodes :
● Référence à un constructeur.
30
Référence à une méthode statique
Une méthode de référence vers une méthode statique permet d'appeler une méthode
statique existante en utilisant l’opérateur de référence (::)
Syntaxe : NomDeLaClasse::nomDeLaMethodeStatique
Exemple:
Si une classe existe déjà pour calculer le carré d'un entier, il n'est pas nécessaire de créer
une expression lambda pour ce cas, car la méthode correspondante est déjà disponible.
31
Référence à une méthode statique
class MathUtils {
// Méthode statique qui calcule le carré d’un entier
public static int carre(int x) {
return x * x;
}
}
32
Référence à une méthode d'instance d'un objet particulier
Une méthode de référence vers une méthode d’instance d’un objet permet d'appeler une
méthode existante d’un objet déjà créé en utilisant l’opérateur de référence (::)
Syntaxe : nomObjet::nomDeLaMethode
Exemple:
Si une classe existe déjà pour retourner le nombres de caractères dans une chaîne, il n'est
pas nécessaire de créer une expression lambda pour ce cas, car la méthode
correspondante est déjà disponible.
33
Référence à une méthode d'instance d'un objet particulier
class StringUtils {
public int getNumberOfLetters(String s) {
return s.length();
}
}
On remarque que cette méthode ressemble au comportement d'un Function car elle
prend une chaîne en entrée et renvoie un entier. Dans ce cas, il est possible d'utiliser
l'opérateur de référence (::) pour appeler la méthode "getNumberOfLetters" plutôt
que de fournir une expression lambda.
34
Référence à une méthode d'instance d'un type particulier
Une méthode de référence vers une méthode d’instance permet d'appeler une méthode
existante d’une classe en utilisant l’opérateur de référence (::)
Syntaxe : NomDeLaClasse::nomDeLaMethode
35
Référence à une méthode d'instance d'un type particulier
Exemple:
Dans cet exemple, nous trions une liste de chaînes de caractères à l'aide de la
méthode “compareTo” de la classe String. Nous utilisons la référence de méthode
pour faire référence à la méthode “compareTo” de chaque chaîne de la liste.
Collections.sort(strings, String::compareTo);
36
Référence à un constructeur
Syntaxe : NomDeLaClasse::new
Exemple:
Imaginons une classe Point qui définit 2 entiers x et y qui représente les coordonnées
d’un point dans un repère orthonormé.
37
Référence à une méthode d'instance d'un objet particulier
39