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
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");