a partir d'exercices propose par Philippe Genoud, Xavier Girod Philippe.Genoud@imag.fr.
Objectifs :
- Aborder au travers d'une application simple les structures de
données
de l'API JAVA 2 ( interfaces et classes Map, List, ArrayList,
HashMap, TreeMap,
Set du package java.util) ainsi que les itérateurs.
- Utiliser les nouvelles fonctionnalités de Java 5 concernant les
classe génériques et les énumérations
On souhaite réaliser
une application
de gestion d'un annuaire téléphonique qui permet d'associer à une
personne
un ou plusieurs numéros de téléphone.
Cette application
s'articulera
autour des classes et interfaces suivante:
- Personne: classe représentant
une personne
définie par un nom, un prénom et une civilité (M., Mlle, Mme).
- NumTel :
classe représentant
un numéro de téléphone, défini par le numéro
proprement dit et un code qui indique la nature du numéro (numéro
de portable, numéro de poste fixe professionnel, numéro de poste
fixe à domicile, numéro de Fax).
- IListeNumTel:
interface définissant les fonctionnalités d'une liste de numéros
de téléphone.
- IAnnuaire: interface
définissant les fonctionnalité
d'un annuaire téléphonique, c'est à dire d'un ensemble
d'associations
<p,ln> avec p
une Personne et ln
une ListeNumTel.
Votre travail
consiste à
réaliser et tester différentes implémentations des interfaces
IListeNumTel et IAnnuaire
en utilisant les services de différentes classes du package
java.util.
Le source de ces différentes classes et interfaces vous est fourni.
Téléchargez et décompressez sur votre compte le fichier
annuaire.zip
qui contient les fichiers suivants :
- NumTel.java
: source de la classe représentant un numéro de téléphone,
- Personne.java
:
sources de la classe représentant une personne,
- IListeNumTel.java
: source de l'interface décrivant les services offert par une
liste
de numéro de téléphones,
- IAnnuaire.java
:
source de l'interface définissant les services offerts par un
annuaire
et qui sera utilisée dans la deuxième partie de ce TD.
- ListeNumTelTest.java:
source d'un programme interactif pour le test des implémentations
de IListeNumtel,
- LectureClavier.java
: classe pour les lectures de valeurs au clavier,
- ImpListeNumtel.class
: le bytecode d'une implémentation de l'interface IListeNumtel
qui vous permettra d'expérimenter avec le programme ListeNumTelTest.
1ère partie :
Première
implémentantion de l'interface
IListeNumTel
L'interface IListeNumTel
définit
une liste des numéros de téléphone pour une personne. Une
liste de numéros n'est jamais vide, elle contient toujours au moins un
numéro.
La spécification
des
méthodes publiques de l'interface IListeNumTel
est donnée dans le tableau suivant:
Liste des méthodes
|
boolean |
ajouter(int index,
NumTel num)
ajoute un numéro
à une position donnée dans la liste, sans effet si le numéro est
déjà présent
dans la liste. |
boolean |
ajouterDebut(NumTel num)
ajoute un numéro
au début de la liste, sans effet si le numéro est déjà présent
dans la liste. |
boolean |
ajouterFin(NumTel num)
ajoute un numéro
à la fin de la liste, sans effet si le numéro est déjà présent
dans la liste. |
boolean |
contientNumero(int num)
Teste la présence
d'un numéro dans la liste. |
java.util.Iterator |
iterator()
Renvoie un itérateur
sur les numéros de téléphone contenus dans la liste. |
int |
nbNumeros()
retourne le
nombre de numéros de la liste (>=1). |
NumTel |
numero(int index)
retourne le
ième numéro de la liste. |
NumTel |
premierNumero()
retourne le
premier numéro de la liste (il existe forcément) |
boolean |
retirer(int num)
Enlève un numéro
de la liste, cette opération n'est possible que si la liste
contient au
moins deux numéros (nbNumero()>1). |
java.lang.String |
toString()
Retourne dans
une chaîne de caractères la séquence des numéros contenu dans
cette liste.
|
Votre premier travail consiste à réaliser et tester une
implémentation
de cette interface. Pour réaliser cette implémentation vous vous
appuyerez sur les services de java.util.List
pour stocker les différents numéros de téléphone.
- A votre avis pourquoi la classe ListeNumtel
délègue-t-elle la gestion de la liste des numéros de
téléphone
à un objet java.util.List plutôt
que d'hériter d'une implémentation de java.util.List
(par exemple java.util.ArrayList)
?
- Ecrire et compiler votre classe ListeNumTel
implémentation de l'interface IListeNumtel
- Tester votre implémentation de l'interface ListeNumtel
avec le programme ListeNumTelTest.
Pour cela vous remplacerer dans la code de ListeNumTelTest
les références à ImpListeNumtel
par des références à votre classe ListeNumTel.
2ème partie :
Réalisation
de la classe Annuaire
Un annuaire permet d'associer à une personne une
liste de numéros de téléphone. Les méthodes de l'interface
IAnnuaire sont les
suivantes
Liste des Méthodes
|
void |
afficher()
affiche l'intégralité
de l'annuaire, sous la forme d'une personne par ligne suivie de
ses numéros
de téléphone. |
boolean |
ajouterEntree(Personne p,
IListeNumTel nums)
ajoute une nouvelle
entrée dans l'annuaire. |
void |
ajouterNumeroDebut(Personne p,
NumTel n)
ajoute un numero
au début de la liste des numéros d'une personne. |
void |
ajouterNumeroFin(Personne p,
NumTel n)
ajoute un numero
à la fin de la liste des numéros d'une personne. |
ListeNumTel |
numeros(Personne p)
retourne les
numéros si la personne est absente retourne null |
java.util.Iterator |
personnes()
renvoie un iterateur
sur l'ensemble des personnes contenues dans l'annuaire |
NumTel |
premierNumero(Personne p)
retourne le
premier numéro d'une personne, si la personne n'est pas dans
l'annuaire
retourne null. |
void |
supprimer(Personne p)
supprime une
personne de l'annuaire. |
void |
supprimer(Personne p,
int n)
supprime un
numero donné pour une personne. |
java.lang.String |
toString()
retourne une
chaîne représentant l'intégralité de l'annuaire. |
Exercice 1 :
a) Réaliser une classe Annuaire
implémentant l'interface IAnnuaire.
On utilisera comme structure de données pour
l'annuaire
une table associative (interface Map)
: la personne jouant le rôle de clé et la liste des numéros
de téléphone étant la valeur associée à cette
clé (on prendra une HashMap comme
implémentation). Dans un premier temps on se contentera d'écrire
une implémentation complète uniquement pour les méthodes
ajouterEntree(Personne,
ListeNumTel),personnes(),
afficher() et numeros()
de la classe Annuaire.
b) Tester ces méthodes avec le petit
programme
principal suivant qui :
- crée un annuaire vide,
- ajoute une entrée pour une personne de nom DURAND, prénom
Sophie, Civilité Mlle. avec comme numéro 151171
- ajoute une entrée pour une personne de nom DUPONT, prénom
Jean, Civilité M. avec comme numéro 151171
- ajoute une entrée pour une personne de nom DUSCHMOL, prénom
Louis, Civilité M. avec comme numéro 146761
- ajoute une entrée pour une personne de nom AARGH, prénom Robert,
Civilité M. avec comme numéro 140361
- affiche le contenu de l'annuaire.
- effectue une recherche des numéros de la personne Sophie DURAND et
une recherche des numéros de Jean DUPONT
public static void main(String[] args) {
// crée un annuaire vide
IAnnuaire an = new Annuaire();
// ajoute deux personnes à l'annuaire
Personne p1 = new Personne(Personne.MLLE,"DURAND","Sophie");
an.ajouterEntree(p1,new ListeNumTel(new NumTel(151171,'D')));
an.ajouterEntree(new Personne(Personne.MR,"DUPONT","Jean"),
new ListeNumTel(new NumTel(151170,'P')));
an.ajouterEntree(new Personne(Personne.MR,"DUSCHMOL", "Louis"),
new ListeNumTel(new NumTel(146761,'P')));
an.ajouterEntree(new Personne(Personne.MR,"AARGHH", "Robert"),
new ListeNumTel(new NumTel(140361,'P')));
// imprime l'annuaire
System.out.println("------------------------------");
System.out.println(an);
System.out.println("------------------------------");
// Recherche des numéros de Sophie DURAND
System.out.println("numeros de " + p1);
System.out.println(an.numeros(p1));
// Recherche des numéros de Jean DUPONT
Personne p2 = new Personne(Personne.MR,"DUPONT","Jean");
System.out.println("numeros de " + p2);
System.out.println(an.numeros(p2));
}
Constatez que la recherche du numéro pour Jean DUPONT a échoué
alors qu'elle a réussi pour Sophie DURAND. Quelle explication donnez
vous à cela ?
c) Modifiez la classe Personne
de manière à corriger les erreurs détectées précédemment.
Exercice 2 :
On voudrait que l'itérateur fournissant les différentes personnes
enregistrées dans l'annuaire permette d'obtenir celles-ci selon
l'ordre
alphabétique, ce qui n'est pas garanti par une HashMap.
Pour cela il vaudrait mieux utiliser comme implémentation de
l'annuaire
un objet instance de la classe TreeMap.
- Dans votre
implémentation
de l'annuaire remplacez HashMap
par TreeMap
- Recompilez
votre application
et exécutez. Quel problème cela pose-t'il ? Quelle doit être la
propriété
de la classe Personne ?
- Faites les
modifications nécessaires,
refaites le test précédent et constatez les modifications lors de
l'affichage
de l'annuaire.
Exercice 3:
Ecrivez l'implémentation complète de la classe Annuaire
et un programme de test de cette classe.
Exercice 4 :
On veut ajouter la
méthode
suivante à l'annuaire:
/**
* donne l'ensemble de toutes les personnes de l'annuaire dont le nom
* débute par une chaîne donnée.
* @param s1 la chaine pour la recherche
* @return l'ensemble des personnes de l'annuaire dont le nom débute
* par s1
*/
public Set entreesPourChaine(String s1)
Réaliser cette évolution et tester cette nouvelle méthode.
(Indication : avant
d'écrire ce code examinez attentivement toutes les méthodes de
TreeMap)
3ème partie : Utilisation de Enum
Exercice: La civilité des personnes est codée
par un entier. Modifier votre application, afin d'utiliser un type
enuméré
pour représenter l'attribut de civilité
4ème partie : Sauvegarde/recharger un annuaire
On veut maintenant pouvoir saugarder un annuaire sous une forme ou
une
autre et on veut pouvoir charger un annuaire "existant". Pour cela
plusieurs
solutions :
-
fichier binaire
-
fichier texte
-
sérialisation de l'annuaire
Inspirez vous de
Agenda.jar en adaptant vos classes des exercice Annuaire
compléter le projet en implémentant
les méthodes :
/**
* enregistrer un Annauire
*/
public void sauvegarderAnnuaire(String sauvegarde)
{
}
public void chargerAnnauire(String fichierAnnuaire)
{
}
dans chacune des classes "AgendaTelBin" , "AgendaTelTxt" ,
"AgendaTelSerialisable" , "AgendaTelProperties" ,
"AgendaTelPropertiesXML"
et commenter l'intéret et les défauts de chacune des
solutions.