Approche Orienté Objet : Methode Equals et HashCode

Résolu/Fermé
Jiko-java Messages postés 186 Date d'inscription dimanche 25 septembre 2016 Statut Membre Dernière intervention 22 juillet 2017 - 13 juil. 2017 à 22:55
Jiko-java Messages postés 186 Date d'inscription dimanche 25 septembre 2016 Statut Membre Dernière intervention 22 juillet 2017 - 21 juil. 2017 à 00:13
Bonjours , voilà j'ai quelque problème en ce qui concerne l'assimilation des méthodes Equals et HashCode je m'explique : En Ayant codé récemment un mini programme à savoir une Collection de Cercle je me suis aperçus que les résultats obtenus en ce qui concerne la comparaison de 2 objets n'étais pas celle que j'attendais voici mes codes :
import java.util.ArrayList;

public class ArrayCircle{

 private ArrayList<Circle> circles;

 public ArrayCircle(){
 circles = new ArrayList<Circle>();
 }
 
 public boolean ajout(Circle circle){
 if(this.contient(circle)) return false;
 
 return circles.add(circle);
 }
 
 public boolean supp(Circle circle){
 return circles.remove(circle);
 }
 
 public boolean contient(Circle circle){
 return circles.contains(circle);
 }
 
 public int sizeCercles(){
 return circles.size();
 }
 
 public String toString(){

 String texte = "Nombre de cercles : " +
  circles.size();  
 for (Circle c : circles){
  texte += "\n" + c;
 }
 return texte;
 
}
}



public Circle(double rayon){
this.rayon = rayon;
}
public void setRayon(double rayon) {
this.rayon = rayon;
}

public double getRayon(){
return rayon;
}
public double calculerAire(){
double aire = rayon * rayon * Math.PI;
return aire;
}

public boolean equals(Object obj) {

if (this == obj) return true;
 
if (obj == null) return false;

if (getClass() != obj.getClass()) return false;

Circle cercle = (Circle) obj;
return this.rayon == cercle.rayon;
}

public int hashCode() {
return ((Double)rayon).hashCode();
}

}


public class TestArrayList {
 public static void main(String[] args) {
 ArrayCircle list = new ArrayCircle();
 Circle circle1 = new Circle(5.0);
 Circle circle2 = new Circle(5.0);
 list.ajout(circle1);
 System.out.println(circle1.equals(circle2));
 System.out.println(list.contient(circle2));
 }
}


Comme vous pouvez vous en apercevoir lors de ma comparaison des cercles: 1 et 2 des objets j'utilise la méthode equals que j'ai au préalable fait, cependant j'ai du mal a comprendre le resultat qu'il retourne à savoir True . Selon moi puisque la methode equals se charche de comparer les référence mémoire ( if (this == obj) return true;) sachant que les 2 instances de cercle n'on pas la même référence puisque C2!=C1 par conséquent il y'a bien en mémoire 2 références distincts Comment peut il considéré que c'est les même objet Merci de m'éclairer .

1 réponse

KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019
Modifié le 14 juil. 2017 à 02:10
Bonjour,

"Comment peut il considéré que c'est les même objet"
Il ne considère pas que ce sont les mêmes objets, il considère que leurs valeurs sont égales, par évaluation de la méthode equals.
Si la méthode equals renvoie true c'est parce que tu lui as demandé de renvoyer true s'ils avaient le même rayon :
return this.rayon == cercle.rayon;
or dans ton code tu as bien deux fois
new Circle(5.0)
, donc même rayon, la méthode equals renvoie true, donc les deux objets sont égaux.
La confiance n'exclut pas le contrôle
0
Jiko-java Messages postés 186 Date d'inscription dimanche 25 septembre 2016 Statut Membre Dernière intervention 22 juillet 2017
14 juil. 2017 à 15:31
Merci Pour votre intervention mais quelque chose m'échappe , Le Equals sert bien a comparer 2 objets en regardant leur "Structure" et ainsi dire si C'est le même objet , Fin Pour moi Si 2 instances sont crées bien qu'ils ont les mêmes valeurs sa ne fait pas d'eux les mêmes Objets , en l’occurrence C'est Leur référence mémoire qui est a comparer . L'évaluation des conditions sont bien Séquentiel donc avant de caster l'obj en un objet de type Circle et de comparer leur rayons, il évalue la première condition à savoir if (this == obj) qui regarde la référence des objets et dans ce cas là il renvoie false pas true selon moi puisque il y'a bien 2 objets distinct crée en mémoire .
0
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019 > Jiko-java Messages postés 186 Date d'inscription dimanche 25 septembre 2016 Statut Membre Dernière intervention 22 juillet 2017
Modifié le 14 juil. 2017 à 16:05
Si tu veux savoir si deux références pointent sur le même objet tu fais
x == y

Cependant en général on ne veut pas savoir si les références sont identiques, ce que l'on veux c'est savoir si la valeur qu'ils représentent sont égales.

Par exemple, avec un String je veux faire
str.equals("toto")
pour savoir si str a effectivement pour valeur "toto", peu importe que ce soit le même objet ou deux objets différent, ce qui m’intéresse c'est de comparer leurs valeurs...

C'est à ça que sert la méthode equals, à pouvoir comparer deux objets sur des critères spécifiques à leurs valeurs, mais c'est du cas par cas, c'est pour ça qu'il faut la redéfinir pour chaque classe qui représente une valeur.

"if (this == obj) qui regarde la référence des objets et dans ce cas là il renvoie false pas true"
Non, il ne renvoie pas false ici. Pour cette première condition le return ne concerne que le cas où c'est vrai (si c'est exactement le même objet ils ont forcément la même valeur). Mais si la condition est fausse, on continue la comparaison avec les conditions suivantes, jusqu'au
return this.rayon == cercle.rayon
qui caractérise l'égalité de valeur spécifique à ta classe.

public boolean equals(Object obj) {
    if (this == obj) return true; // pas de return false ici
    // si this != obj on continue avec un autre critère
    if (obj == null) return false; // pas de return true ici
    // si obj != null on continue avec un autre critère
    if (getClass() != obj.getClass()) return false; // pas de return true ici
    // si obj est de la même classe, on continue avec un autre critère
    Circle cercle = (Circle) obj; // on est sûr que c'est la même classe
    return this.rayon == cercle.rayon; // return true ou false, selon
}
0
Jiko-java Messages postés 186 Date d'inscription dimanche 25 septembre 2016 Statut Membre Dernière intervention 22 juillet 2017
21 juil. 2017 à 00:13
Ahh d'accord merci pour cet éclaircissement je comprends Mieux a présent :) .
0