Mise en oeuvre des lambdas en Java 8
Attention lire le chapitre sur les interfaces avant d'aborder la lecture de ce chapitre.
Extrait de la formation que j'anime
Franck SIMONConsultant architecte logiciel Java EE et IoT (Internet des Objets) à Transtel
2. antislashn.org Java 8 - les lambdas 2 / 20
Introduction
● Une expression lambda permet d'implémenter une
nouvelle opération sans avoir à créer une nouvelle
classe
● le type des arguments et de la valeur de retour doivent
correspondre à ceux de la méthode de l'interface
fonctionnelle
r = Calcul.compute(10, 2, (x,y) -> x*y);
3. antislashn.org Java 8 - les lambdas 3 / 20
Introduction
● Fonction lambda ou fonction anonyme
● fonction n'ayant pas de nom
● les instructions de la fonction lambda suivent une syntaxe
particulière
● il est possible de
– la stocker lambda dans une variable de type interface
fonctionnelle
– la retourner depuis une méthode, ou une autre fonction
● JSR 335
4. antislashn.org Java 8 - les lambdas 4 / 20
Introduction
● Expression lambda
● une expression lambda est une notation abrégée d'une
méthode fonctionnelle
● une fonction lambda peut renvoyer une valeur
– si lambda à une seule expression, la valeur renvoyée est
l'expression elle-même
– si lambda à un bloc de code, la valeur renvoyée est fournie par
un ou plusieurs return
String[] tabString = {"a","b","c","d","e","f"};
Arrays.asList(tabString).forEach(s -> System.out.println(s));
5. antislashn.org Java 8 - les lambdas 5 / 20
Syntaxe
● Syntaxe de base
● nouvel opérateur, l'opérateur flèche: ->
– tiret suivi du signe >
● les arguments doivent être entre ( )
– si pas d'argument, parenthèses vides
– si un seul argument, les parenthèses peuvent être omises
– le type des arguments peut être indiqué
● le corps
– est une simple expression, la valeur de cette expression est
alors renvoyée
– un bloc d'instructions, entre { }, peut contenir un ou plusieurs
return
arguments -> corps
6. antislashn.org Java 8 - les lambdas 6 / 20
Portée des variables
● Une expression lambda se comporte comme un bloc
de code { }
● comme les classes anonymes, la lambda peut avoir accès
à certaines variables définies dans le contexte engobant
● Il est possible d'utiliser dans le corps de la lambda
● des paramètres passés à l'expression
● des variables définies dans le corps de la lambda
● des variables final du corps englobant
● des variables effectivement final
– depuis Java 8 : variables non déclarées final mais qui ne sont
jamais modifiées
7. antislashn.org Java 8 - les lambdas 7 / 20
Syntaxe
● Les paramètres
● une lambda peut avoir aucun, un ou plusieurs paramètres
● le type des paramètres peut-être précisé, ou inféré par le
compilateur
– pas possible de mixer typage et inférence
● les paramètres sont entourés par des parenthèses et
séparés par des virgules
– aucun paramètre : parenthèses vides
– un paramètre : parenthèses facultatives
● les types doivent correspondre à ceux de l'interface
fonctionnelle
8. antislashn.org Java 8 - les lambdas 8 / 20
Exemple
● Quelques exemples
● sortis de leur contexte, ce qui explique l'absence de ;
() -> System.out.println("hi")
(x,y) -> x+y
(Point p, int x) -> p.add(x)
Arrays.asList(tabString).sort((e1,e2)->e1.compareTo(e2));
(x,y) -> {if(x<y)
return y;
else
return x;}
Operation op = (x,y) -> x % y;
9. antislashn.org Java 8 - les lambdas 9 / 20
Utilisation
● Une expression lambda est passée en tant que
paramètre à une méthode
● alternative à l'implémentation d'une interface
● elle définit une implémentation pour une interface
fonctionnelle
● l'interface fonctionnelle est typée de manière statique
– inférence de type par le compilateur
10. antislashn.org Java 8 - les lambdas 10 / 20
Utilisation
● Une lambda ne peut être utilisée que si le
compilateur peut en identifier l'utilisation cible
● appelée "target type"
● interface fonctionnelle
● La lambda est transformée par le compilateur en une
instance de l'interface fonctionnelle
11. antislashn.org Java 8 - les lambdas 11 / 20
Utilisation
● Exemple d'implémentation d'un Thread
● classe anonyme
● lambda
Thread th = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Traitement à effectuer dans le thread");
}
});
th.start();
Thread th = new Thread(()-> System.out.println("Traitement à effectuer dans le thread") );
th.start();
12. antislashn.org Java 8 - les lambdas 12 / 20
Références de méthode
● Raccourci syntaxique pour créer un expression
lambda qui invoque une méthode ou un constructeur
● lambda : méthode anonyme dont le type est une interface
fonctionnelle
● référence à une méthode : invoque un constructeur ou
une méthode statique
● Nouvel opérateur ::
13. antislashn.org Java 8 - les lambdas 13 / 20
Références de méthodes
● Quatre types de références de méthodes
● référence à une méthode statique
– class::staticMethod
● référence à une méthode d'instance
– oject::method
● référence à un construteur
– class::new
● référence une méthode d'un type donné
– class::method
14. antislashn.org Java 8 - les lambdas 14 / 20
Référence de méthode
● Appelé une méthode d'instance
● préciser l'instance dans la référence à la méthode
● préciser le type dans la référence à la méthode
– alors il faut fournir l'instance en paramètre
15. antislashn.org Java 8 - les lambdas 15 / 20
Références de méthodes
● Exemple
● le corps de l'expression lambda ne fait qu'invoquer une
méthode : remplacement par une référence à une
méthode
JButton button = new JButton();
button.addActionListener(event -> System.out.println(event));
JButton button = new JButton();
button.addActionListener(System.out::println);
16. antislashn.org Java 8 - les lambdas 16 / 20
Références de méthodes
● Exemple de référence à une méthode statique
public class MainStaticReference {
public static void main(String[] args) {
// expression lambda
new Thread(() -> compute()).start();
// référence à une méthode statique
new Thread(MainStaticReference::compute).start();
}
// méthode statique
static void compute() {
System.out.println("traitement par le thread : " + Thread.currentThread().getName());
}
}
17. antislashn.org Java 8 - les lambdas 17 / 20
Références de méthodes
● Exemple de référence à une méthode d'instance
public class ContactComparator {
public int comparerByNom(Contact c1, Contact c2) {
return c1.getNom().compareTo(c2.getPrenom());
}
}
Contact[] contacts = {
new Contact("Mme","Sasseur","Marlène"),
new Contact("M","Naudin","Fernand"),
new Contact("M","Michalon","Léonard")
};
ContactComparator comparator = new ContactComparator();
Arrays.sort(contacts, comparator::comparerByNom);
System.out.println(Arrays.deepToString(contacts));
18. antislashn.org Java 8 - les lambdas 18 / 20
Références de méthodes
● Exemple de référence de méthode d'une instance
arbitraire
String[] jours = {"lundi","mardi","mercredi","jeudi","vendredi","samedi","dimanche"};
// expression Lambda
Arrays.sort(jours, (j1,j2) -> j1.compareToIgnoreCase(j2));
// référence vers méthode d'un type unbound
Arrays.sort(jours, String::compareToIgnoreCase);
19. antislashn.org Java 8 - les lambdas 19 / 20
Références
● Référence à un constructeur
● le compilateur va déterminé quelle est la signature du
constructeur en fonction du contexte
public interface ContactSupplier {
Contact create(String civilite, String nom, String prenom);
}
ContactSupplier supplier = Contact::new;
Contact contact = supplier.create("M", "Perrin", "François");