Expressions lambda Java - Mémo
Nous pouvons depuis la version 8 de Java faire des choses intéressantes avec les expressions lambda, notamment avec toutes les fonctions pour avec les streams. Voici les 10 choses utiles à faire avec les expressions lambda.
Remplacer les classes internes
Les classes internes pouvaient être assez longue et difficilement lisible. Maintenant nous pouvons utiliser une expression lambda beaucoup plus concise.
// Avant Java 8 avec les classes internes
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Avant Java 8 avec les classes internes");
}
}).start();
// Après Java 8 avec les expressions lambda
new Thread(() -> System.out.println("Java 8 avec les expressions lambda")).start();
Ou encore avec les Handler de JavaFx :
Button btn = new Button("OK");
btn.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler < MouseEvent > () {
@Override
public void handle(MouseEvent e) {
System.out.println("Assez long...");
}
});
btn.addEventHandler(MouseEvent.MOUSE_CLICKED, e -> System.out.println("Beaucoup plus court"));
Attention, le mot-clé this dans une classe interne et dans une expression lambda n'a pas la même portée. Dans une classe interne, this correspond à l'objet créé. Alors que dans une expression lambda, le mot-clé this correspond à la classe où vous avez écrit l'expression lambda.
La nouvelle boucle forEach
La nouvelle boucle est aussi beaucoup plus courte et supporte en plus les tâches parallèles.
//Avant Java 8
List < String > fruits = Arrays.asList("Pomme", "Poire", "Abricot", "Pêche", "Mangue");
for (String fruit: fruits)
System.out.println(fruit);
//Après Java 8
Arrays.asList("Pomme", "Poire", "Abricot", "Pêche", "Mangue")
.forEach(System.out::println);
Filtres et Prédicats
Les filtres et prédicats permettent de réduire une collection en filtrant les éléments. Voici comment ils fonctionnent :
fruits = Arrays.asList("Pomme", "Poire", "Abricot", "Pêche", "Mangue", "Citron");
System.out.println("Affiche tous les fruits commencant par 'P' : ");
fruits.stream()
.filter(fruit -> fruit.toLowerCase().startsWith("p"))
.forEach(System.out::println);
System.out.println("Affiche tous les fruits finissant par 'E' : ");
fruits.stream()
.filter(fruit -> fruit.toLowerCase().endsWith("e"))
.forEach(System.out::println);
System.out.println("Affiche tous les fruits avec 6 lettres : ");
fruits.stream()
.filter(fruit -> fruit.length() == 6)
.forEach(System.out::println);
System.out.println("Affiche aucun fruits : ");
fruits.stream()
.filter(fruit -> false)
.forEach(System.out::println);
System.out.println("Affiche les fruits avec 6 lettres et commençant par 'po' : ");
fruits.stream()
.filter(fruit -> fruit.length() == 5)
.filter(fruit -> fruit.toLowerCase().startsWith("po"))
.forEach(System.out::println);
System.out.println("Affiche les fruits avec 5 lettres et commençant par 'po' : ");
Predicate < String > longueurDe5 = mot -> mot.length() == 5;
Predicate < String > lettrePo = mot -> mot.toLowerCase().startsWith("po");
fruits.stream()
.filter(longueurDe5.and(lettrePo))
.forEach(System.out::println);
Map
Map permet de faire des opérations sur un stream et d'en obtenir un nouveau. Imaginons que l'on veuille diviser tous les éléments d'une liste par deux.
List entiers = Arrays.asList(2, 4, 8, 16, 32, 64, 128, 256, 512, 1024);
System.out.println("Divise les entiers " + entiers + " par 2 : ");
entiers.stream()
.map(x -> x / 2)
.forEach(System.out::println);
Grâce au IntStream nous pouvons calculer la somme d'une liste d'Integer.
System.out.println("La somme de la liste " + entiers + " est égale à : " +
entiers.stream().mapToInt(Integer::intValue).sum());
Collecter une nouvelle liste
Pour convertir un stream en liste, il faut se servir de la fonction collect.
System.out.println("Collecte tous les fruits commencant par 'po' : ");
System.out.println(
fruits.stream()
.filter(fruit -> fruit.toLowerCase().startsWith("po"))
.collect(Collectors.toList()));
Pour obtenir une chaîne de caractères, on peut se servir de Collectors.joining
System.out.println("Affiche les fruits commencant par 'P' séparés par des virgules : ");
System.out.println(
fruits.stream()
.filter(fruit -> fruit.toLowerCase().startsWith("p"))
.collect(Collectors.joining(",")));
Enlever les doublons
Pour enlever les doublons il faut se servir de la fonction distinct. Cette fonction se sert de la fonction equals donc n'oubliez pas de l'implémenter.
entiers = Arrays.asList(12, 65, 16, 300, 250, 16, 65);
System.out.println("Affiche la liste " + entiers + " sans les doublons : ");
System.out.println(entiers.stream().distinct().collect(Collectors.toList()));
Statistiques
Pour obtenir des statistiques sur une collection de nombres on peut se servir de la classe IntSummaryStatistics, DoubleSummaryStatistics ou LongSummaryStatistics.
System.out.println("Affiche les statistiques de la liste " + entiers + " : ");
IntSummaryStatistics stats = entiers.stream().mapToInt(x -> x).summaryStatistics();
System.out.println("Maximum : " + stats.getMax());
System.out.println("Minimum : " + stats.getMin());
System.out.println("Moyenne : " + stats.getAverage());
System.out.println("Total : " + stats.getSum());
System.out.println("Nombre d'éléments : " + stats.getCount());
Limiter la taille d'un stream
Imaginons que nous voulons obtenir les trois premiers éléments du flux et les afficher dans la console.
System.out.println("Affiche les 3 premiers fruits : ");
fruits.stream()
.limit(3)
.forEach(System.out::println);
Trier un stream
Pour trier un stream on peut se servir de la fonction sorted.
System.out.println("Affiche la liste dans l'ordre alphabétique : ");
fruits.stream()
.sorted()
.forEach(System.out::println);
La fonction peut utiliser la méthode compareTo.
System.out.println("Affiche la liste par ordre alphabétique descendant : ");
fruits.stream()
.sorted((fruit1, fruit2) -> fruit2.compareTo(fruit1))
.forEach(System.out::println);
Sauter les éléments dans un stream
Pour sauter les éléments d'un stream on peut se servir de la fonction skip.
System.out.println("Saute les deux premiers éléments du flux : ");
fruits.stream()
.skip(2)
.forEach(System.out::println);
Commentaires
Enregistrer un commentaire