:: Enseignements :: ESIPE :: E4INFO :: 2014-2015 :: Java Avancé ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) |
Lambda, method reference et stream
|
Exercice 1 - Le compte est bon
Le but de cet exercice est de découvrir comment utiliser
des lambdas et des streams.
-
On cherche à compter le nombre d'occurence d'un mot dans une liste.
List<String> list = Arrays.asList("hello", "world", "hello", "lambda");
System.out.println(count(list, "hello"));
Ecrire le code de la méthode count sachant que le compteur
est un entier long.
-
On cherche à écrire une méthode count2 sémantiquement équivalente
(qui fait la même chose) que count mais en utilisant l'API
des Stream.
Comment obtenir une Stream à partir d'un objet de type List ?
L'idée, ici, est de filtrer le stream pour ne garder que les mots égaux
au mot passé en paramètre puis de compter ceux-ci.
Quelle est le nom des méthodes permettant respectivement de filtrer un stream
et de compter le nombre d'élement ?
La méthode qui permet de filtrer prend un objet de type Predicate<T>
en paramètre. Dans notre cas, quelle est le type correspondant à T ?
Indiquer le code permettant de créer une lambda filtrant sur le mot passé en
paramètre que l'on peut déclarer en tant que Predicate
Ecrire le code de la méthode count2.
Exercice 2 - En majuscule
Le but de cet exercice est de découvrir comment utiliser
en plus des lambdas et des streams, des méthodes reférences.
-
On cherche écrire une méthode prenant en paramètre une liste de chaîne de caractères
et renvoyant une nouvelle liste contenant les chaînes de caractère en majuscule.
List<String> list = Arrays.asList("hello", "world", "hello", "lambda");
System.out.println(upperCase(list));
Ecrire la méthode upperCase dans un premier temps sans utiliser
l'API des Stream.
-
On cherche maintenant à écrire une méthode upperCase2 faisant
la même chose.
Comment peut-on utiliser la méthode Stream.map ici ?
Pour stocker le résultat dans une nouvelle liste, l'idée est de créer
la liste pour d'ajouter chaque mot dans la liste.
public static List<String> upperCase2(List<String> words) {
ArrayList<String> uppercases = new ArrayList<>();
...
pour demander l'ajout, on utilisera sur le stream la méthode forEach.
Ecrire le code de la méthode upperCase2 en utilisant des lambdas.
-
En fait, au lieu d'utiliser des lambdas, il est possible dans cette exemple
d'utiliser la syntaxe des réferences de méthodes avec l'opérateur ::
(coloncolon).
Ecrire une méthode upperCase3 qui utilise la syntaxe des
référence de méthodes.
-
En fait, au lieu d'utiliser forEach, il est plus pratique d'utiliser
la méthode collect avec comme Collector
celui renvoyé par la méthode Collectors.toList().
Ecrire une méthode upperCase4 en utilisant le collector
Collectors.toList().
Exercice 3 - Comptons sur une réduction
Le but de cet exercice est de découvrir comment utiliser
effectuer une reduction sur un stream.
Lors du premier exercice, nous avons utilisé la méthode count
qui retourne un entier long, on souhaite maintenant écrire une nouvelle
méthode count3 qui renvoie un entier sur 32 bits.
Pour cela, une fois les mots filtrés, nous allons transformer
(avec map) chaque mot en 1 (le nombre) puis nous allons
avec la méthode reduce faire l'aggregation des valeurs.
-
Expliquer pourquoi, nous n'allons pas utiliser la méthode map
mais la méthode mapToInt ?
-
Ecrire le code de la méthode méthode count3.
Exercice 4 - Evaluation de vitesse
On cherche à savoir parmis les 3 façons d'écrire
count
quelle est la plus rapide.
Nous allong pour cela utiliser une liste définie par le code suivant
List<String> list2 =
new Random(0)
.ints(1_000_000, 0, 100)
.mapToObj(Integer::toString)
.collect(Collectors.toList());
-
Expliquer ce que contient la variable locale list2.
-
On cherche à écrire une méthode printAndTime permettant
de calculer le temps d'exécution de l'appel à la méthode count
sur la list2.
Pour calculer le temps d'exécution, on demande le temps avant puis
le temps après et si l'on soustrait les deux temps, on trouve le temps
d'exécution.
long start = System.nanoTime();
... // faire le calcul
long end = System.nanoTime();
System.out.println("result " + result);
System.out.println(" elapsed time " + (end - start));
Tester ce code en appelant la méthode count().
-
On cherche maintenant A NE PAS dupliquer le code pour le calcul avec
count2 et count3 mais à utiliser la méthode
printAndTime et de passer en paramètre la méthode count
qui doit être appelé.
Expliquer pourquoi on a besoin de l'interface LongSupplier
sachant que l'on va appeler printAndTime de cette façon
printAndTime(() -> count(list2, "33"));
printAndTime(() -> count2(list2, "33"));
printAndTime(() -> count3(list2, "33"));
Ecrire le nouveau code de printAndTime.
-
Expliquer les résultats obtenus.
© Université de Marne-la-Vallée