Comparaison d`objets, collection sans doublons et collections triées
Transcription
Comparaison d`objets, collection sans doublons et collections triées
Java Comparaison d'objets, collection sans doublons et collections triées G. Vieillechaize ch 4/4.2 equals, collections sans doublons, collections triées .doc v1.1____________________________________________ Comparaison d'objets, collection sans doublons et collections triées On repart de l'exemple Visiteur On va voir successivement • une liste de noms des visiteurs, sans doublons (liste d'objets d'un type prédéfini String) • une liste des visiteurs, sans doublons (liste d'objets d'un type défini par l'application) • une liste de noms des visiteurs, triée • une liste des visiteurs, triée 1 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. 1.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> nomsVisiteurs = 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 Page 1 Java Comparaison d'objets, collection sans doublons et collections triées G. Vieillechaize ch 4/4.2 equals, collections sans doublons, collections triées .doc v1.1____________________________________________ ... // ajouter son nom à la liste s'il n'existe pas encore if (!nomsVisiteurs.contains(v.getNom())) { nomsVisiteurs.add(v.getNom()); } else { // message: nom en double 1.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 redéfinir equals( ) la signature de equals() dans Object est public boolean equals(Object obj) voir l'exemple: dossier collections / liste triée il faut respecter la signature dans Contact 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 Visiteur: 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 visiteurss 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< Visiteur> liste = new HashSet<Visiteur>(); liste.add(new Contact("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 visiteurs 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, sans tenir compte de la casse) 2 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 2 Java Comparaison d'objets, collection sans doublons et collections triées G. Vieillechaize ch 4/4.2 equals, collections sans doublons, collections triées .doc v1.1____________________________________________ 2.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) 2.2 Définir et utiliser compareTo()et Comparable La liste de noms peut être triée sans problème, parce que les noms sont des String, et que la classe String ets "triable" (elle implémente Comparable) et implémente la méthode nécessaire 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) Si on veut une liste triée de contacts - on reprend l'exemple "HashSet de visiteurs" et remplacer HashSet par TreeSet ⇒ on obtient une ClassCastException car Visiteur doit implémenter l'interface Comparable et donc la méthode compareTo() - 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 visiteurs 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 3