:: Enseignements :: Master :: M1 :: 2013-2014 :: Java Avancé ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | java.util, full stream |
Le but de ce TD est, dans un premier temps, d'utiliser l'API
java.util.stream
puis, dans un second temps, d'implanter la partie exécutable d'un petit language
de requêtes.
Un sénateur des Etats-Unis d'amérique vient de compléter avec succès une campagne
de dons lui permettant d'envisager sereinement les élections.
En effet, un ensemble de généreux donateurs (
Donor) ont répondu à son
appel et ont versé différentes sommes d'argent, et il veut maintenant savoir
des choses comme quel est le montant global des sommes versées, ou qui
sont ses principaux donateurs.
Lorsqu'un donateur effectue une contribution, il signale son nom, son sexe,
l'entreprise pour qui il travaille ainsi que la somme versée.
Sous forme d'objet, on se retrouve avec les classes
Donor et
Company.
Exercice 1 - Un flux
-
Avant de vraiment commencer, quel est le problème dans la façon
dont l'attribut gender de la classe Donor est défini.
Comment faire mieux ?
Implanter les changements qui s'imposent.
-
On souhaite calculer le montant global des sommes versées pour une liste
de Donor.
Où doit on écrire la méthode getTotalDonation ?
Ecrire le code de cette méthode.
-
On souhaite de plus trouver la liste de tous les Donor masculins pour
une liste de Donor passée en paramètre.
Ecrire la méthode getAllMales
Noter que, comme le code qui teste si un donateur est masculin ou pas
n'est pas très joli, il serait bien d'avoir une méthode isMale.
Vérifier, avec les tests unitaires suivants, que tout va bien pour ces deux méthodes.
DonorsTest
-
En fait, il est possible d'utiliser une écriture plus concise pour les méthodes
getTotalDonation et getAllMales en utilisant l'interface
java.util.stream.Stream.
Il existe une méthode stream() sur l'interface List qui
permet d'obtenir un Stream. Ce stream possède des méthodes
map, filter et collect.
Expliquer à quoi servent les méthodes map, filter et
collect et ré-implanter les méthodes getTotalDonation et
getAllMales en utilisant un stream.
Note: pour la méthode collect, il va falloir aider un peu Eclipse
car celui-ci n'implante pas correctement l'inférence de type.
Indiquer explicitement les types des arguments de la méthode permettant
de créer le Collector est en général suffisant.
-
On veut, de plus, une méthode getImportantDonors qui renvoie la liste
des 10 plus importants donateurs ayant donné plus de 10 000 dollars
triés de celui ayant donné le plus à celui ayant donné le moins.
Implanter cette méthode en utilisant un stream.
-
Enfin, on veut une méthode getDonorByCompany qui range dans une table de hachage
les donateurs ayant la même entreprise (Company).
Exercice 2 - Mon SQL like
Bien sûr, écrire du code à chaque fois que le sénateur veut faire une extraction
est une bonne nouvelle si on est payé à la ligne, mais sinon, bof.
Vous vous mettez donc d'accord pour créer un langage de requêtage
qui va lui permettre d'interroger sa base de donateurs sans que vous
soyez dans les parages.
Et comme vous aimez bien ré-inventer la roue, au lieu d'utiliser SQL,
vous vous créez votre propre langage dont voici une description succinte.
all // liste tous les donateurs
name // liste le nom de tous les donateurs
name limit 10 // liste les 10 premiers donateurs
all sorted by name // liste tous les donateurs triés
// par ordre decroissant en fonction du nom
all sorted by name limit 10 // meme chose qu'avant mais les 10 premiers
all with name less than HHH // liste les donateurs dont le nom est inférieur
// a HHH dans l'ordre lexicographique
Pour cela, vous utiliserez la classe
Query qui représente, sous
forme d'objet, une query textuelle.
La classe
QueryParser
déjà écrite, permet de prendre une chaîne de caractères et de créer
un objet
Query ou, si la chaîne de caractères est mal formée,
de lever l'exception
ParseException.
On ne vous demande pas de comprendre le code de la classe
QueryParser,
vous devez la considérer comme une boite noire qui crée un objet
Query,
seule la méthode
execute doit être implantée.
-
On souhaite, dans un premier temps, implanter les projections uniquement
en utilisant le champs selector d'une Query.
Pourquoi la méthode execute renvoie une List<Object> ?
On amerait plutôt une List<T> avec le bon T.
Expliquer pourquoi remplacer List<Object> par List<T>
rend le code unsafe.
Comment doit on modifier la signature de la méthode execute
pour que le code de execute ne soit plus unsafe ?
-
Implanter les projections all, name, gender, company et amount.
-
Implanter la notion de limit.
-
Doit on faire le tri du sorted by avant ou après la projection ?
Implanter le sorted by.
-
Implanter le with en déléguant le traitement à la classe With.
© Université de Marne-la-Vallée