TD de Programmation Orientée Objet
s

Interfaces - Collections

Corrigé

dernière modification par Philippe.Genoud@imag.fr.

Philippe Genoud, Xavier Girod

Une version de cette correction (avec les sources complets) est disponible dans le fichier corrigeTd7.zip

1ère partie : implémenter ListeNumTel avec une ArrayList

 

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


/**
 * Représente un ensemble de numéros de téléphone, cet ensemble contient au moins
 * un numéro (pas de liste vide).
 *
 * Une ArrayList est utilisée pour stocker les éléments de la liste.
 *
 */
public class AL_ListeNumTel implements ListeNumTel {
    
    /**
     * La liste des numéros
     */
    protected List listNum_;
    
    //------------------------------------------------
    // Constructeur
    //------------------------------------------------
    
    /**
     * Construit une liste contenant le numéro spécifié en paramètre
     * @param numTel le numéro à insérer dans la liste
     */
    public AL_ListeNumTel(NumTel numTel) {
        listNum_ = new ArrayList();
        listNum_.add(numTel);
    }
    
    
    //------------------------------------------------------
    // implementation de l'interface ListeNumTel.
    //-------------------------------------------------------
    
    
    /** 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.
     * @param int index la position d'insertion dans la liste
     * @param num le numéro à ajouter
     * @return true si le numéro a été ajouté? false si l'ajout
     *        n'a pas eu lieu car la liste contient déjà le numéro.
     *
     */
    public boolean ajouter(int index, NumTel num) {
                if (! listNum_.contains(num) ) {
            listNum_.add(index,num);
            return true;
        }
        else
            return false;
    }
    
    /** ajoute un numéro au début de la liste, sans effet si le numéro est déjà
     * présent dans la liste.
     * @param num le numéro à ajouter
     * @return true si le numéro a été ajouté? false si l'ajout
     *        n'a pas eu lieu car la liste contient déjà le numéro.
     *
     */
    public boolean ajouterDebut(NumTel num) {
                    return ajouter(0,num);
    }
    
    /** ajoute un numéro à la fin de la liste, sans effet si le numéro est déjà
     * présent dans la liste.
     * @param num le numéro à ajouter
     * @return true si le numéro a été ajouté? false si l'ajout
     *        n'a pas eu lieu car la liste contient déjà le numéro.
     *
     */
    public boolean ajouterFin(NumTel num) {
                  return ajouter(listNum_.size(), num);
    }
    
    /**
     * Teste la présence d'un numéro dans la liste.
     * @param num le numéro à rechercher.
     * @return true si la liste contient le objet Numtel dont le numéro est
     *         identique à num, false sinon
     *
     */
    public boolean contientNumero(int num) {
        return listNum_.contains(new NumTel(num));
    }
    
    /** 
     * Renvoie un itérateur sur les numéros de téléphone contenus dans la liste.
     *
     * @return un iterateur permettant le parcours des numéros de la liste
     *
     */
    public Iterator iterator() {
        return listNum_.iterator();
    }
    
    /** retourne le nombre de numéros de la liste (>=1).
     * @return nombre de numéros présents dans la liste.
     *
     */
    public int nbNumeros() {
        return listNum_.size();
    }
    
    /** retourne le ième numéro de la liste, null si la liste contient
     * moins de i numéros.
     * @param index la position du numéro à rechercher
     * @return le numero de la liste à la position index.
     *
     */
    public NumTel numero(int index) {
        return  (NumTel) listNum_.get(index);
    }
    
    /** retourne le premier numéro de la liste (il existe forcément)
     * @return le premier numero de la liste.
     *
     */
    public NumTel premierNumero() {
        return  (NumTel) listNum_.get(0);
    }
    
    /** 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). Si la liste ne contient contient
     * qu'un seul numéro cette opération est sans effet. De même si le numéro spécifié
     * n'est pas présent dans la liste.
     * Cette méthode retourne un booléen qui indique si cette liste de numéros de téléphone
     * a été affectée par l'opération de retrait.
     *
     * @param num le numero à enlever.
     *
     * @return true si un NumTel dont le numéro est num a été retiré de la liste,
     *         false si la liste ne contient plus qu'un seul numéro ou si il n'y
     *         a pas dans la liste de NumTel de numéro num.
     *
     */
    public boolean retirer(int num) {
        if (nbNumeros() > 1)
            return listNum_.remove(new NumTel(num));
        else
            return false;
    }
    
    /** Retourne dans une chaîne de caractères la séquence des numéros contenu dans
     * cette liste. Dans la chaîne résultat les numéros sont séparés par des virgules.
     * 
     * exemple:
     * 0476088634 (D), 0654789045 (P), 0476615277 (T)
     * 
     * @return la chaine contenant la séquence des numéros.
     *
     */
    public String toString() {
        String res =  listNum_.toString();
        return res.substring(1, res.length() - 1);  // pour enlever '[' et ']'
    }
    
}

2 ème partie Réalisation de la classe Annuaire

Exercice 1

a) la classe M_Annuaire incomplète. Seules les méthodes afficher, ajouterEntree, numeros et personnes sont implémentées. Le main suggéré dans l'enoncé du TP a été ajouté.

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;


/**
 * implementation partielle de l'interface Annuaire en utilsiant une HashMap.
 *
 * @author  genoud
 */
public class M_Annuaire implements Annuaire {
    
    /**
     * la table associative qui gère les données de l'annuaire
     */
    private Map data_;
    
    //-------------------------------------------------------
    // constructeurs
    //--------------------------------------------------------
    
    /** Construit un annauire vide */
    public M_Annuaire() {
        data_ = new HashMap();
    }
    
    
    //------------------------------------------------------
    // implémentation de l'interface Annuaire
    //------------------------------------------------------
    
    /**
     * affiche l'intégralité de l'annuaire, sous la forme d'une personne par ligne
     * suivie de ses numéros de téléphone.
     *
     */
    public void afficher() {
        
        for (Iterator it = personnes(); it.hasNext(); ) {
            Personne p = (Personne) it.next();
            System.out.println(p + " : " + data_.get(p));
        }
    }
    
    /** ajoute une nouvelle entrée dans l'annuaire. Si p n'existe pas: on crée une nouvelle
     * association (p,nums) et le booleen true est retourné; sinon le booleen
     * false est retourné et la méthode est sans effet.
     *
     * @param p la personne
     * @param nums sa liste de numeros
     * @return true si l'entrée a été ajoutée, false si la personne
     *        p était déjà présente dans l'annuaire
     *
     */
    public boolean ajouterEntree(Personne p, ListeNumTel nums) {
        if (data_.containsKey(p)) {
            // la personne est déjà présente
            return false;
        }
        else {
            // la personne n'est pas présente
            data_.put(p,nums);
            return true;
        }
    }
    
    /** ajoute un numero au début de la liste des numéros d'une personne.
     * Si la personne n'existe pas on crée une nouvelle entrée pour cette personne avec
     * comme liste de numéros associée la liste constituée du numéro passé en paramètre.
     *
     * @param p la personne
     * @param n le numero à ajouter
     *
     */
    public void ajouterNumeroDebut(Personne p, NumTel n) {
    }
    
    /** ajoute un numero à la fin de la liste des numéros d'une personne.
     * Si la personne n'existe pas on crée une nouvelle entrée pour cette personne avec
     * comme liste de numéros associée la liste constituée du numéro passé en paramètre.
     *
     * @param p la personne
     * @param n le numero à ajouter
     *
     */
    public void ajouterNumeroFin(Personne p, NumTel n) {
    }
    
    /** retourne les numéros  si la personne est absente retourne null
     * @param o la personne pour laquelle on consulte les numeros.
     * @return la liste des numéros de la personne si celle-ci est présente dans l'annuaire,
     *         null sinon.
     *
     */
    public ListeNumTel numeros(Personne p) {
        
        return(ListeNumTel) data_.get(p);
    }
    
    /** renvoie un iterateur sur l'ensemble des personnes contenues dans l'annuaire
     * @return l'iterateur
     *
     */
    public Iterator personnes() {
        Set keys = data_.keySet();
        return keys.iterator();
    }
    
    /** retourne le premier numéro d'une personne, si la personne n'est pas dans l'annuaire retourne null.
     *
     * @param p la personne dont on recherche le numéro
     * @return son numero, null si p n'est pas présente dans l'annuaire.
     *
     */
    public NumTel premierNumero(Personne p) {
        return null;  // en attendant une implementation
    }
    
    /** supprime une personne de l'annuaire. Sans effet si la persoone n'est pas présente
     * dans l'annuaire.
     * @param p la personne à retirer de l'annuaire.
     *
     */
    public void supprimer(Personne p) {
    }
    
    /** supprime un numero donné pour une personne.
     * Si ce numéro est le seul numéro pour la  personne, la personne est retirée de l'annuaire.
     * Sans effet si la personne n'est pas présente dans l'annuaire.
     * @param p la personne pour laquelle un numéro doit être supprimé.
     * @param n le numero a supprimer.
     *
     */
    public void supprimer(Personne p, int n) {
    }
    
    public static void main(String[] args) {
        
        // crée un annuaire vide
        Annuaire an = new M_Annuaire();
        
        // ajoute deux personnes à l'annuaire
        Personne p1 = new  Personne(Personne.MLLE,"DURAND","Sophie");
        an.ajouterEntree(p1,new AL_ListeNumTel(new NumTel(151171,'D')));
        
        an.ajouterEntree(new Personne(Personne.MR,"DUPONT","Jean"),
        new AL_ListeNumTel(new NumTel(140361,'P')));
        
        an.ajouterEntree(new Personne(Personne.MR,"DUSCHMOL", "Louis"), 
new AL_ListeNumTel(new NumTel(140361,'P')));

an.ajouterEntree(new Personne(Personne.MR,"AARGHH", "Robert"),
new AL_ListeNumTel(new NumTel(140361,'P'))); // imprime l'annuaire System.out.println("------------------------------"); an.afficher(); 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)); } }

b) exécution

La trace d'exécution produite :

------------------------------
Mr Jean DUPONT : 140361 (P)
Mlle Sophie DURAND : 151171 (D)
Mr Robert AARGHH : 140361 (P)
Mr Louis DUSCHMOL : 140361 (P)
------------------------------
numeros de Mlle Sophie DURAND 151171 (D) numeros de Mr Jean DUPONT null
Pourquoi cela ne marche pas ? Pourquoi on ne retrouve pas le numéro de téléphone de Jean DUPONT ?

parceque la fonction hashCode utilisée pour les personnes est celle héritée de Object et elle est cohérente avec la méthode equals héritée aussi de Object.

La méthode equals est définie dans la classe Object de la manière suivante :
x.equals(y) --> true
si l'objet référencé par x est identique (le même en mémoire) à l'objet référencé par y (en d'autres termes si x == y).

La méthode hashCode retourne quant à elle un entier qui correspond à l'adresse mémoire de l'objet. Ainsi, deux objets Personne qui ont les même attributs ne sont pas égaux et n'ont donc pas le même hashcode.

Quand on recherche les numéros de téléphone de Jean DUPONT, on utilise un objet distinct de celui qui a été employé pour ranger ces numéros dans la Map. Son hashcode n'est pas le même que celui utilisé pour ranger les valeurs dans la table. Aussi quand on fait la recherche dans la table est-il normal de ne rien trouver pour l'entrée désignée par ce hashcode.

c) Modification la classe Personne de manière à corriger les erreurs détectées précédemment.

Il faut redéfinir equals de manière à ce que deux personnes qui ont les mêmes attributs soient considérées égales, et la fonction de hashCode pour intégrer dans le calcul les attributs utilisés pour tester l'égalité (deux personne égales doivent avoir le même hashcode)..

  public boolean equals(Object o) {
    if (! (o instanceof Personne) ) 
      return false;

    Personne p = (Personne) o;
    return nom_.equals(p.nom_) && prenom_.equals(p.prenom_) && civilite_ == p.civilite_;
    // ATTENTION : les STring sont des objets, bien penser à utiliser equals
    // et non pas == pour comparer des chaînes
  }


  public int hashCode() {
    String nomPlusPrenom = nom_ + prenom_;
    return nomPlusPrenom.hashCode() + civilite_;  // allez regarder la définition de hashCode
                                                  // dans la classe String
  }

l'exécution de M_Anuaire donne alors bien le résultat escompté.

------------------------------
Mr Jean DUPONT : 140361 (P)
Mlle Sophie DURAND : 151171 (D)
Mr Robert AARGHH : 140361 (P)
Mr Louis DUSCHMOL : 140361 (P)
------------------------------
numeros de Mlle Sophie DURAND 151171 (D) numeros de Mr Jean DUPONT 140361 (P)

Exercice 2

Après avoir remplacé HashMap par TreeMap dans la classe M_Annuaire et recompilé on obtient l'erreur suivante à l'exécution lorsque l'on tente d'ajouter une entrée à l'annuaire:

java.lang.ClassCastException
at java.util.TreeMap.compare(TreeMap.java:1081)
at java.util.TreeMap.getEntry(TreeMap.java:341)
at java.util.TreeMap.containsKey(TreeMap.java:199)
at M_Annuaire.ajouterEntree(M_Annuaire.java:62)
at M_Annuaire.main(M_Annuaire.java:152)
Exception in thread "main"

l'erreur provient du fait que pour que le TreeMap fonctionne il faut qu'il existe une relation d'ordre sur les éléments utilisés comme clé et pour cela que la classe représentant ceux-ci implémente l'interface Comparable de java.lang. Ce qui n'est pas le cas de la classe Personne d'où l'erreur d'exécution.

Pour remédier à ce problème il faut donc que personne implémente cette interface.

on change la déclaration de la classe de la manière suivante :

public class Personne implements Comparable {
implements Comparable {

et on ajoute une implémentation de la méthode compareTo

  //------------------------------------------
  // implementation de l'interface Comparable
  //------------------------------------------
  public int compareTo(Object o) {
      if (! (o instanceof Personne) )
          throw new ClassCastException("impossible de comparer un " + 
             o.getClass().getName() + " à une Personne");
      
      Personne p = (Personne) o;
      String s = this.nom_ + this.prenom_ + this.civilite_ ;
      return s.compareTo(p.nom_ + p.prenom_ + p.civilite_);
  }
	  

Après ces modfications, l'exécution d'afficher donne bien un annuaire dans l'ordre alphabétique.

	    ------------------------------
        Mr Robert AARGHH : 140361 (P)
        Mr Jean DUPONT : 140361 (P)
        Mlle Sophie DURAND : 151171 (D)
        Mr Louis DUSCHMOL : 140361 (P)
        ------------------------------
      

Exercice 3:

implémentation complète de la classe Annuaire

import java.util.TreeMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;


/**
 * implementation complète de l'interface Annuaire en utilsiant une TreeMap.
 *
 * @author  genoud
 */
public class M_Annuaire implements Annuaire {
    
    /**
     * la table associative qui gère les données de l'annuaire
     */
    private Map data_;
    
    //-------------------------------------------------------
    // constructeurs
    //--------------------------------------------------------
    
    /** Construit un annauire vide */
    public M_Annuaire() {
        data_ = new TreeMap();
    }
    
    
    //------------------------------------------------------
    // implémentation de l'interface Annuaire
    //------------------------------------------------------
    
    /**
     * affiche l'intégralité de l'annuaire, sous la forme d'une personne par ligne
     * suivie de ses numéros de téléphone.
     *
     */
    public void afficher() {
        
        for (Iterator it = personnes(); it.hasNext(); ) {
            Personne p = (Personne) it.next();
            System.out.println(p + " : " + data_.get(p));
        }
    }
    
    /** ajoute une nouvelle entrée dans l'annuaire. Si p n'existe pas: on crée une nouvelle
     * association (p,nums) et le booleen true est retourné; sinon le booleen
     * /false est retourné et la méthode est sans effet.
     *
     * @param p la personne
     * @param nums sa liste de numeros
     * @return truesi l'entrée a été ajoutée, false si la personne
     *        p était déjà présente dans l'annuaire
     *
     */
    public boolean ajouterEntree(Personne p, ListeNumTel nums) {
        if (data_.containsKey(p)) {
            // la personne est déjà présente
            return false;
        }
        else {
            // la personne n'est pas présente
            data_.put(p,nums);
            return true;
        }
    }
    
    /** ajoute un numero au début de la liste des numéros d'une personne.
     * Si la personne n'existe pas on crée une nouvelle entrée pour cette personne avec
     * comme liste de numéros associée la liste constituée du numéro passé en paramètre.
     *
     * @param p la personne
     * @param n le numero à ajouter
     *
     */
    public void ajouterNumeroDebut(Personne p, NumTel n) {
        if (data_.containsKey(p)) {
            // la personne est déjà présente
            // on rajoute le numero n à la liste des numéros de cette personne
            ((ListeNumTel) data_.get(p)).ajouterDebut(n);
        }
        else {
            // la personne n'est pas présente
            data_.put(p,new AL_ListeNumTel(n));
        }
    }
    
    /** ajoute un numero à la fin de la liste des numéros d'une personne.
     * Si la personne n'existe pas on crée une nouvelle entrée pour cette personne avec
     * comme liste de numéros associée la liste constituée du numéro passé en paramètre.
     *
     * @param p la personne
     * @param n le numero à ajouter
     *
     */
    public void ajouterNumeroFin(Personne p, NumTel n) {
        if (data_.containsKey(p)) {
            // la personne est déjà présente
            // on rajoute le numero n à la liste des numéros de cette personne
            ((ListeNumTel) data_.get(p)).ajouterFin(n);
        }
        else {
            // la personne n'est pas présente
            data_.put(p,new AL_ListeNumTel(n));
        }
    }
    
    /** retourne les numéros pour une personne,  si la personne est absente retourne null
     * @param o la personne pour laquelle on consulte les numeros.
     * @return la liste des numéros de la personne si celle-ci est présente dans l'annuaire,
     *         null sinon.
     *
     */
    public ListeNumTel numeros(Personne p) {
        
        return(ListeNumTel) data_.get(p);
    }
    
    /** renvoie un iterateur sur l'ensemble des personnes contenues dans l'annuaire
     * @return l'iterateur
     *
     */
    public Iterator personnes() {
        Set keys = data_.keySet();
        return keys.iterator();
    }
    
    /** retourne le premier numéro d'une personne, si la personne n'est pas dans l'annuaire retourne null.
     *
     * @param p la personne dont on recherche le numéro
     * @return son numero, null si p n'est pas présente dans l'annuaire.
     *
     */
    public NumTel premierNumero(Personne p) {
        ListeNumTel num = (ListeNumTel) data_.get(p);
        return (num == null)?null:num.premierNumero();
    }
    
    /** supprime une personne de l'annuaire. Sans effet si la personne n'est pas présente
     * dans l'annuaire.
     * @param p la personne à retirer de l'annuaire.
     *
     */
    public void supprimer(Personne p) {
        if (data_.containsKey(p))
            data_.remove(p);
    }
    
    /** supprime un numero donné pour une personne.
     * Si ce numéro est le seul numéro pour la  personne, la personne est retirée de l'annuaire.
     * Sans effet si la personne n'est pas présente dans l'annuaire.
     * @param p la personne pour laquelle un numéro doit être supprimé.
     * @param n le numero a supprimer.
     *
     */
    public void supprimer(Personne p, int n) {
        if (data_.containsKey(p)) {
            ListeNumTel num = (ListeNumTel) data_.get(p);
            if (num.nbNumeros() > 1)
                num.retirer(n);
            else
                data_.remove(p);
        }
    }
    
}

 

un programme de test interactif sur le modèle de celui proposé pour les listes de numéros de téléphone

public class AnnuaireTest {
    
    /**
     * l'annuaire
     */
    private static Annuaire annu;
    
    /**
     * affiche un menu proposant les différentes opérations possibles sur l'annuaire
     */
    private static void affMenu() {
        System.out.println("-----------------------------------------------");
        System.out.println("1 : créer un annuaire vide ");
        System.out.println("2 : ajouter une personne ");
        System.out.println("3 : ajouter un numéro à une personne en début de liste ");
        System.out.println("4 : ajouter un numéro à une personne en fin de liste ");
        System.out.println("5 : afficher tous les numéros d'une personne ");
        System.out.println("6 : afficher le premier numéro d'une personne ");
        System.out.println("7 : supprimer une personne ");
        System.out.println("8 : supprimer un numéro d'une personne ");
        System.out.println("9 : afficher tout le contenu de l'annuaire ");
        System.out.println("0 : quitter l'application ");
        
        System.out.print("\nVotre choix : ");
    }
    
    
    private  static NumTel lireNumTel() {
        System.out.print("numero : ");
        int num = LectureClavier.lireEntier();
        System.out.print("type (T : Fixe professionnel, D : Fixe domicile, P : Portable, F : Fax, ? inconnu)");
        char type = LectureClavier.lireChar();
        return new NumTel(num,type);
    }
    
    private static Personne lirePersonne(){
        System.out.print("nom : ");
        String nom = LectureClavier.lireChaine();
        System.out.print("prénom : ");
        String prenom = LectureClavier.lireChaine();
        System.out.print("civilite " + Personne.MR + " : Mr " + Personne.MME + " : Mme "
        + Personne.MLLE + " : Mlle ");
        int civil = LectureClavier.lireEntier();
        return new Personne(civil,nom,prenom);
    }
    
    private static void ajouterPersonne() {
        System.out.println("\nPersonne à ajouter");
        Personne p = lirePersonne();
        System.out.println("\nliste de ses numéros");
        System.out.println("Premier numéro");
        NumTel num = lireNumTel();
        ListeNumTel l = new AL_ListeNumTel(num);
        System.out.println("autre numéro O/N ?");
        boolean encore = LectureClavier.lireOuiNon();
        while (encore) {
            num = lireNumTel();
            l.ajouterFin(num);
            System.out.println("autre numéro O/N ?");
            encore = LectureClavier.lireOuiNon();
        }
        annu.ajouterEntree(p,l);
    }
    
    
    private static void ajouterNumeroDebut() {
        System.out.println("\nPersonne à laquelle le numéro doit être ajouté");
        Personne p = lirePersonne();
        System.out.println("numéro de téléphone à ajouter au début de la liste : ");
        NumTel num = lireNumTel();
        annu.ajouterNumeroDebut(p,num);
    }
    
    private static void ajouterNumeroFin() {
        System.out.println("\nPersonne à laquelle le numéro doit être ajouté");
        Personne p = lirePersonne();
        System.out.println("numéro de téléphone à ajouter en fin de la liste : ");
        NumTel num = lireNumTel();
        annu.ajouterNumeroDebut(p,num);
    }
    
    private static void numeros() {
        System.out.println("\nPersonne pour laquelle vous voulez les numéros");
        Personne p = lirePersonne();
        ListeNumTel l = annu.numeros(p);
        System.out.println("ses numéros sont : " + l);
    }
    
    private static void premierNumero() {
        System.out.println("\nPersonne pour laquelle vous voulez le 1er numéros");
        Personne p = lirePersonne();
        NumTel n = annu.premierNumero(p);
        System.out.println("son premier numéro est : " + n);
    }
    
    private static void supprimerNumero() {
        System.out.println("\nPersonne pour laquelle vous voulez supprimer un numéro");
        Personne p = lirePersonne();
        System.out.print("numéro à supprimer ");
        int n = LectureClavier.lireEntier();
        annu.supprimer(p,n);
    }
    
    private static void supprimerPersonne() {
        System.out.println("\nPersonne que vous voulez retirer de l'annuaire");
        Personne p = lirePersonne();
        annu.supprimer(p);
    }
    
    
    public static void main(String[] args){
        
        annu = new M_Annuaire();
        
        boolean encore = true;
        do {
            affMenu();
            int rep = LectureClavier.lireEntier();
            
            switch (rep) {
                case 0:  System.out.print("Voulez vous vraimment quitter l'application O/N ");
                encore = ! LectureClavier.lireOuiNon();
                break;
                case 1:  annu = new M_Annuaire();
                break;
                case 2:  ajouterPersonne();
                break;
                case 3:  ajouterNumeroDebut();
                break;
                case 4:   ajouterNumeroFin();
                break;
                case 5:  numeros();
                break;
                case 6:  premierNumero();
                break;
                case 7:  supprimerPersonne();
                break;
                case 8:  supprimerNumero();
                break;
                case 9: annu.afficher();
                break;
                default:  System.out.println("Mauvais numéro de commande");
                break;
            } // fin du switch
        } while (encore);
    }
    
}// AnnuaireTest

exercice 4 : rechercher les personnes dans l'annuaire dont le nom commence par une chaîne donnée.

Il faut rajouter à l'annuaire la méthode suivante :

    /** 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) {
        
        // on construit une chaine s2 dont le dernier
        // caractère est le suivant (selon l'ordre
        // alphabétique) du dernier caractère de s1.
        char[] carac = s1.toCharArray();
        carac[carac.length-1] += 1;
        String s2 = new String(carac);
        
        // on crée deux personnes dont le nom est
        // respectivement s1 et s2
        Personne fromPers = new Personne(s1,"");
        Personne toPers = new Personne(s2,"");
        
        // on cherche la "sous-map" qui correspond
        // à toutes les personnes dont le nom est
        // compris entre le nom de fromP et le nom de
        // toP
        SortedMap s = ((TreeMap)data_).subMap(fromPers, toPers);
        
        // le résultat est l'ensemble des clés de cette
        // "sous-map"
        return s.keySet();
    }