:: Enseignements :: ESIPE :: E4INFO :: 2016-2017 :: Java Avancé ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | Examen de Java Avancée (2ième session) |
Rappel, vous devez configurer le workspace d'eclipse (File > Switch WorkSpace) pour
qu'il corresponde au répertoire EXAM présent dans le home
de votre session de TP noté.
Rappel 2: le jdk9 est situé dans le répertoire /usr/local/app/java9
Attention à bien lire le sujet (et chaque question) en entier avant de commencer à écrire du code.
Exercice 1 - Des personnes, des adresses et des courriers ...
Le but de cet exercice est de simuler la gestion d'envoi de courrier papier à des adresses de personnes dans une entreprise.
Une entreprise est composée de personnes qui ont une ou plusieurs adresses sachant que la première adresse (dans l'ordre d'insertion), si elle existe, est considérée comme l'adresse principale.
Pour simplifier, les personnes sont identifiées par un nom et les adresses ne sont composées que d'un nom de rue.
L'application consiste en 3 classes Company, Person et Address ainsi
qu'une classe d'aide (helper class) Utils.
-
Dans un premier temps, nous allons nous concentrer sur la classe qui représente une adresse.
Corriger le code du fichier Address.java
pour que l'ensemble des tests JUnit
AddressTest.java
passent.
-
Maintenant que classe des adresses fonctionne, nous allons passer à l'implantation des personnes dans la classe
Person.java.
Pour créer une personne, nous aurons également besoin de la classe
Company.java qui représente une entreprise et que nous améliorerons plus tard.
On va maintenant faire en sorte que l'on puisse associer une ou plusieurs adresses à une personne. On doit pouvoir:
-
Ajouter une adresse avec la méthode addAddress; la méthode doit lever une exception si la même adresse a déjà été ajoutée.
-
Supprimer une adresse avec la méthode removeAddress, si cette adresse est l'une des adresses associées à une personne.
-
Renvoyer l'ensemble des adresses associées à une personne,
avec la méthode getAddresses;
l'ensemble renvoyé doit être non mutable.
-
On veux pouvoir afficher une personne avec le format suivant :
si il n'y a pas d'adresse associée, on affiche uniquement le nom de la personne;
si il y a des adresses associées, celles-ci doivent apparaître après le nom de la personne suivi d'un ':' et séparées par des virgules suivies d'un espace, dans l'ordre d'insertion, dans le cas où il y a plusieurs adresses.
Par exemple, si pedro a deux adresses "addr1" et "addr2" qui lui sont associées, l'affichage sera
pedro: addr1, addr2
Modifier le code en conséquence.
Note: il y a une solution à base de Stream en une ligne.
-
On souhaite que la première adresse ajoutée ait un rôle un peut spécial (cf. plus loin).
Ajouter une méthode getPrimaryAddress qui renvoie la première adresse,
en utilisant un Optional car il peut ne pas y avoir d'adresse associée.
-
On souhaite de plus ajouter une méthode getFirstAddressesAsView qui prend un entier n
et renvoie l'ensemble des (au plus) n premières adresses associées (dans l'ordre d'insertion). L'ensemble renvoyé doit être non mutable.
En terme d'implantation, on peut voir que renvoyer un ensemble des n premiers éléments d'un autre ensemble
est indépendant des éléments eux-mêmes, donc il est possible d'écrire de façon générique une méthode
getFirstAsView (dans la classe Utils.java)
qui prend en paramètre un entier et un ensemble et renvoie un nouvel ensemble contenant les n premiers éléments de l'ensemble en paramètre.
Attention, l'ensemble renvoyé doit agir comme une vue, toute modification de l'ensemble pris en paramètre doit être visible dans l'ensemble renvoyé et ce même après l'appel de la méthode getFirstAsView.
Il ne faut donc, en aucun cas, dupliquer les éléments de l'ensemble pris en paramètre vers la vue.
-
Écrire la méthode getFirstAsView dans la classe Utils en validant que le code
marche grâce aux tests unitaires UtilsTest.java.
Note: dans le cas où n est supérieur au nombre d'éléments de l'ensemble pris en paramètre,
la taille de l'ensemble renvoyé est le nombre d’éléments de l'ensemble pris en paramètre.
Implantation: vous pouvez utiliser la classe AbstractSet.
-
Puis écrire la méthode getFirstAddressesAsView dans la classe Person en utilisant la méthode précédemment écrite.
-
Nous allons maintenant passer à l'implantation de la classe Company.
Les tests unitaires sont dans la classe CompanyTest.java.
-
Dans un premier temps, faire en sorte que l'on ne puisse pas créer des personnes ayant le même nom dans une même Company.
Note: il y a une solution en une à deux lignes.
-
Puis implanter getPersonFromName qui permet d'obtenir
une personne (ou pas, sous forme d'un Optional) précédemment créée à partir de son nom.
La méthode getPersonFromName doit s'exécuter en temps constant : O(1) en moyenne.
-
Enfin, implanter la méthode getAllPersons qui renvoie sous forme d'une collection non mutable l'ensemble des personnes crées par une Company.
-
On cherche maintenant à grouper les envois de courrier. L'idée est de mettre dans une même enveloppe autant de courriers que de personnes habitant à une même adresse. Pour cela, nous allons créer une méthode
getAllPersonByPrimaryAddress qui renvoie une Map qui associe à une adresse principale une liste des personnes dont c'est l'adresse principale.
Note: il existe un collecteur nommé groupingBy.
Note 2: si vous n'y arrivez pas avec le collecteur, vous pouvez tout faire à la main.
-
En fait, pour certains documents, il y a une obligation d'envoyer ceux-ci à l'ensemble des personnes vivant à une même adresse
(même si cela veut dire qu'une personne recevra le même document à plusieurs adresses).
Nous allons pour cela développer une nouvelle méthode getAllPersonByAddress, qui regroupe les personnes associées à chaque adresse.
Note: Si vous le faîtes avec des Stream, n'oubliez pas que flatMap est votre ami et que Map.entry() permet de créer des paires.
Note 2: Vous pouvez aussi le faire sans utiliser de Stream.
-
Enfin, il se peut qu'une enveloppe se perde et l'on voudrait pouvoir avoir la liste de toutes les personnes à une adresse donnée, sans nécessairement avoir à recalculer toute la Map.
Pour cela, écrire une méthode getAllPersonAt qui prend en paramètre une adresse et renvoie une liste des personnes qui sont associées à cette adresse.
© Université de Marne-la-Vallée