1 Collection simple ArrayList
Transcription
1 Collection simple ArrayList
Java Exercices sur les Collections H.ZINSOU ch 3 / collections .doc v1.2 (Visiteur)____________________________________________________ On repart de l'exemple Visiteur 1 Collection simple ArrayList On va utiliser dans un 1er temps une collection ArrayList en remplacement du tableau Visiteur[] visiteurs une ArrayList fonctionne comme un tableau de taille variable de plus une ArrayList permet d'intercaler un élément avec add(position, élément) de supprimer un élément en décalant automatiquement les autres avec remove(élément) vider la liste avec clear() etc. définir la liste de Visiteurs sous la forme d'une ArrayList public class MonAppli { ArrayList listeVisiteur = new ArrayList(); ... main (...) { ou mieux, une liste paramétrée (à partir de Java 5) ArrayList<Visiteur> listeVisiteurs = new ArrayList<Visiteur>(); remplir la liste listeVisiteurs.add( // selon les constructeurs que l'on a défini pour Visiteur new Visiteur(civilite, nom, email); si on a défini une liste paramétrée Visiteur v = visiteurs.get(rang); ( si on a défini une liste non paramétrée, on doit écrire quelque chose comme Object obj = listeVisiteur.get(2); car une collection non paramétrée contient des instances de Object il faut alors convertir (opérateur de cast) l'élément trouvé dans la liste: Visiteur visiteur = (Visiteur) listeVisiteurs.get(2); ) parcourir la collection en java 5, on parcourt la liste simplement avec for (Visiteur v : listeVisiteurs) { System.out.println(v); } ( en java 4 ou antérieur, on peut parcourir l'ArrayList en utilisant un indice (méthode propre aux arrayLists) for (int i=0; i<= listeVisiteurs.size(); i++) { Visiteur visiteur = (Visiteur) listeVisiteurs.get(i); ou on peut utiliser une instance de Iterator (méthode valable pour toutes les collections) Iterator iter = visiteurs.iterator(); // hasNext() renvoie false si l'élément courant est le dernier de liste while (iter.hasNext(){ Visiteur visiteur = (Visiteur) iter.next(); Page 1 Java Exercices sur les Collections H.ZINSOU ch 3 / collections .doc v1.2 (Visiteur)____________________________________________________ ) On va voir successivement une liste de noms des visiteurs, sans doublons (nom est un objet du type prédéfini String) une liste des visiteurs, sans doublons (Visiteur est un type défini par l'application) une liste de noms des visiteurs, triée une liste des visiteurs, triée 2 Collection sans doublon et égalité d’objets Les collections sans doublons utilisent le hashcode de l'objet pour éliminer les doublons Le hashcode doit être cohérent avec le résultat de equals(): si 2 objets sont égaux, ils doivent avoir le même hashcode. 2.1 Première liste sans doublons: HashSet de noms on veut gérer et afficher une liste sans doublons de tous les noms de visiteurs connus: voir l'exemple: dossier collections / liste sans doublons on utilisera pour cela un HashSet le HashSet maintiendra automatiquement une liste sans doublons des noms créer la liste public class Testeur { private HashSet<String> nomsVisiteur = new HashSet<String>(); remplir la liste ...private void saisirVisiteur() { // créer le visiteur Visiteur v = new Visiteur(nom...); // ajouter son nom à la liste nomsVisiteurs.add(v.getNom()); parcourir la liste private void listerNomsVisiteurs() { for (String nom : nomsVisiteurs) { System.out.println(nom); vérifier le contenu de la liste: a) vérifier que les doublons sont supprimés si on ajoute un nom qui existe déjà, l'ancien nom est remplacé on peut le vérifier en récupérant le booléen retourné par add() boolean estNouveau = nomsVisiteurs.add(v.getNom()); System.out.println("nom nouveau ? " + estNouveau); b) vérifier les doublons avant d'ajouter le nouveau nom on peut aussi vérifier si l'élément existe déjà, avant d'insérer, en utilisant contains() ...private void saisirVisiteur() { // créer le visiteur ... // ajouter son nom à la liste s'il n'existe pas encore if (!nomsVisiteurs.contains(v.getNom())) { nomsVisiteurs.add(v.getNom()); Page 2 Java Exercices sur les Collections H.ZINSOU ch 3 / collections .doc v1.2 (Visiteur)____________________________________________________ } else { // message: nom en double 2.2 Liste d'objets sans doublons: surcharge de equals() et hashCode() l'exemple de la liste de noms était très simple, parce que le nom du Visiteur est un String, et que la classe String implémente les méthodes nécessaires equals() et hashCode(), qui permettent de savoir si le nom existe déjà dans la liste pour les objets Visiteur, il faut surcharger la définition de equals( ) fournie par la classe Object voir l'exemple: dossier collections / liste triée la signature de equals() dans Object est public boolean equals(Object obj) il faut respecter la signature dans Visiteur mêmes visibilité, même type retourné et même paramètre: class Visiteur { public boolean equals(Object obj) {... utiliser instanceof pour vérifier que le paramètre reçu est bien une instance de Contact: if ( ! (obj instanceof Visiteur)) return false; c’est la responsabilité du concepteur de savoir ce que c’est que 2 contacts « égaux » : par exemple, pour faire simple, on considère que 2 visiteurs de même nom sont la même personne if(((Visiteur)o).nom.equals(this.nom)) return true; return false; il faut auusi redéfinir hashCode() puisque 2 visiteurs égaux sont 2 visiteurs de même nom, on basera le hashcode de Visiteur sur celui du nom: public int hashCode() { return nom.hashCode(); } on peut maintenant construire une collection sans doublons de Visiteur HashSet liste = new HashSet(); liste.add(new Visiteur("Premier", "Un", '[email protected]")); verifier le résultat de add() et le contenu de la liste lorsqu'on ajoute un élément et lorsqu'on ajoute un doublon. pour les vrais amateurs: il serait plus exact de considérer que 2 visteurs sont la même personne s'ils ont le même email; cela demandera qu'on définisse equals() dans Email (deux emails seraient égaux si égalité de pseudo, serveur et domaine) 3 Collection triée et tri des objets En plus de equals() et hashCode(), les collections triées utilisent compareTo() pour trier la liste Les objets placés dans la collection doivent implémenter Comparable Page 3 Java Exercices sur les Collections H.ZINSOU ch 3 / collections .doc v1.2 (Visiteur)____________________________________________________ 3.1 Collection triée de noms Il suffit de reprendre l'exemple "HashSet de noms" et remplacer HashSet par TreeSet le TreeSet maintiendra automatiquement une liste de noms sans doublon et triée; la liste sera triée dans "l'ordre naturel" des éléments (l'ordre alphabétique pour des instances de String) La liste de noms peut être triée sans problème, parce que les noms sont des String, et que la classe String est "triable" (elle implémente Comparable) et implémente la méthode nécessaire compareTo() 3.2 Définir et utiliser compareTo()et Comparable Si on veut une liste triée de contacts - on reprend l'exemple "HashSet de contacts" et remplacer HashSet par TreeSet on obtient une ClassCastException car Contact doit implémenter l'interface Comparable et donc la méthode compareTo() compareTo() est destinée à fournir un moyen de trier les objets retourne 0 si equals() est vrai entre les 2 objets à trier retourne -1 si l'objet this est avant l'objet reçu en paramètre, dans l'ordre de tri souhaité retourne +1 si l'objet this est après la signature est int compareTo(Object objet) Pour implémenter l'interface Comparable on déclare class Visiteur implements Comparable { et on implémente class Visiteur implements Comparable { public int compareTo(Object o) { ... si on veut une liste des viisteurs triée par noms, l'implémentation pourra être public int compareTo(Object o) { if (o == null) //erreur if (! (o instanceof Visiteur)) // erreur Visiteur autre = (Visiteur) o; return this.nom.compareTo(autre.nom); } _____________________________________ Page 4 exemple : dossier solutions / 3.1