:: Enseignements :: Licence :: L3 :: 2016-2017 :: Programmation Objet avec Java ::
|
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'occurences d'un mot dans une liste.
List<String> list = Arrays.asList("hello", "world", "hello", "lambda");
System.out.println(count(list, "hello"));
Écrire 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) à count mais en utilisant l'API
des Stream.
Comment obtenir un 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.
Quel sont les méthodes permettant respectivement de filtrer un stream
et de compter le nombre d’éléments ?
La méthode qui permet de filtrer prend un objet de type Predicate<T>
en paramètre. Dans notre cas, quel 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
Écrire 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 " method references ".
-
On cherche à écrire une méthode prenant en paramètre une liste de chaînes de caractères
et renvoyant une nouvelle liste contenant les chaînes de caractères en majuscules.
List<String> list = Arrays.asList("hello", "world", "hello", "lambda");
System.out.println(upperCase(list));
Écrire 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 puis 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.
Écrire le code de la méthode upperCase2 en utilisant des lambdas.
-
En fait, au lieu d'utiliser des lambdas, il est possible dans cet exemple
d'utiliser la syntaxe des références de méthodes avec l'opérateur ::
(coloncolon).
Écrire 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().
Écrire 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
effectuer une réduction 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'agrégation des valeurs.
-
Expliquer pourquoi nous n'allons pas utiliser la méthode map
mais la méthode mapToInt ?
-
Écrire le code de la méthode méthode count3.
Exercice 4 - Evaluation de vitesse
On cherche à savoir, parmi les 3 façons d'écrire
count,
quelle est la plus rapide.
Nous allons 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));
Écrire le code de printAndTime.
-
On souhaite également calculer le temps d’exécution avec
d'autres méthodes, comme count2 par exemple.
Comment faire pour NE PAS dupliquer le code pour le calcul du temps d’exécution?
Quelle interface fonctionnelle doit-t-on utiliser sachant que l'on va appeler
printAndTime de la façon suivante?
printAndTime(() -> count(list2, "33"));
printAndTime(() -> count2(list2, "33"));
printAndTime(() -> count3(list2, "33"));
Écrire le nouveau code de printAndTime.
-
Expliquer les résultats obtenus.
© Université de Marne-la-Vallée