Juste pour info, l'early-access Lambda est assez complète : http://jdk8.java.net/lambda/
Il y a de quoi bien s'amuser même si l'inference des types n'est pas finalisé (du coup il faut parfois caster explicitement, ce qui alourdit la syntaxe).
Quelques exemples vites fait :
1 - On peut effectuer des itérations internes sur les éléments Iterable :
1 2 3 4 5 6 7 8 9 10
| Iterable<String> iterable = ...
// Ceci :
for (String s : iterable) {
System.out.println(s);
}
// Peut-être remplacé par cela :
iterable.forEach((String s) -> {
System.out.println(s);
}); |
Par defaut cela revient à la même chose (c'est à dire à utiliser un Iterator), mais chaque implémentation peut définir sa propre implémentation de forEach() plus optimisé (c'est le cas par exemple d'ArrayList qui effectuera directement le parcours sur son tableau interne).
Au passage ce code peut être encore plus compacte, de diverses manières :
1 2 3 4 5 6 7 8 9 10 11 12 13
| // Expression Lambda complète, dont l'expression peut prendre plusieurs lignes :
iterable.forEach((String s) -> {
System.out.println(s);
});
// Lorsque le code de l'expression se résume à une ligne,
// on peut se passer des crochet et du point-virgule final { ... ;}
iterable.forEach((String s) -> System.out.println(s));
// Le type du (ou des) paramètre est déduit du contexte
// il est donc possible de s'en passer :
iterable.forEach((s) -> System.out.println(s));
// Lorsqu'on n'a qu'un seul et unique paramètre,
// on peut se passer des parenthèses :
iterable.forEach(s -> System.out.println(s)); |
Mieux encore, lorsqu'on se contente d’appeler une méthode, et que sa signature correspond à l'interface fonctionnelle, on peut remplacer l'expression Lambda par un pointeur de méthode (notez bien les doubles deux-points :: )
iterable.forEach(System.out::println);
Cette méthode forEach() est encore plus intéressante sur les Map :
1 2 3 4 5 6 7 8 9 10 11 12 13
| Map<String, Object> map = ...
// Avec un Iterator on se ballade plein de chose inutile :
for (Map.Entry<String,Object> e : map.entrySet()) {
String k = e.getKey();
Object v = e.getValue();
System.out.println(k + " = " + v);
}
// Alors qu'on peut aller droit à l'essentiel avec les expr. lambda :
map.forEach((k,v) -> {
System.out.println(k + " = " + v);
}); |
L'API de Collections profite des "Default Method" pour se doter de quelques méthodes utiles, exemple :
1 2 3 4 5 6 7 8 9 10
| List<String> list = ...
// Passer tous les éléments de la liste en majuscule :
list.replaceAll(String::toUpperCase);
// Supprimer tous les éléments de moins de 4 caractères :
list.removeAll(s -> s.length() < 4);
// Trier les éléments selon l'ordre naturel (compareTo()) :
list.sort(Comparators.naturalOrder());
// Trier les éléments selon leurs tailles :
list.sort(Comparators.comparing(String::length)); |
Note : cette dernière ligne ne fonctionne pas encore à cause de l'inférence des types qui n'est pas finalisé, et pour le moment il faut spécifier explicitement le paramétrage Generics, ce qui ne sera plus le cas dans la version finale :
list.sort(Comparators.<String,Integer>comparing(String::length));
Mais le plus gros ajout vient des streams : lorsqu'on utilise un stream, on peut filtrer ou modifier les valeurs de la source de données, sans modifier cette source.
Quelques exemples (loin d'être exhaustif) :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| Collection<String> coll = ...
// On prend tous les éléments de 6 caractères,
// en ignorant les doublons,
// que l'on va trier par taille,
// puis convertir en majuscule,
// pour finalement afficher les valeurs :
coll.stream()
.filter(s -> s.length() < 6)
.uniqueElements()
.sorted(Comparators.<String, Integer>comparing(String::length))
.map(String::toUpperCase)
.forEach(System.out::println);
// Même chose que ci-dessus, mais en stockant le résultat dans une ArrayList :
List<String> result = coll.stream()
.filter(s -> s.length() < 6)
.uniqueElements()
.sorted(Comparators.<String, Integer>comparing(String::length))
.map(String::toUpperCase)
.into(new ArrayList<String>());
// Afficher seulement 5 éléments, après le 10ième
// (cela permet de mettre en place un système de pagination)
coll.stream()
.slice(10, 5)
.forEach(System.out::println);
// Recherche de la valeur minimum, selon l'ordre naturel :
String min = coll.stream()
.min(Comparators.naturalOrder())
.get(); |
La grosse force des "stream" étant de pouvoir paralléliser les traitements.
En effet il suffit d'utiliser la méthode parallelStream() à la place de stream() pour que le traitement soit effectuer en parallèle (si cela est possible bien entendu).
a++
Partager