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

Documents pareils