Implementation de comparable ne marche pas

hasnaa-1 Messages postés 10 Date d'inscription   Statut Membre Dernière intervention   -  
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   -
Bonjour a tous

dans mon programme j ai besoin d implementer l interface comparable afin de trier les element dans treeset selon l ordre qui convient mais malheureusement ca ne marche pas :(
car lorsque je veux tester l existence d un élément qu les meme cordonne d un element existant dans ma collection contains retourne false
voila l algo d'implementation de Comparable
package optimisation;
public class Point implements Comparable {
int x;
int y;
int L;
int xan;
int yan;
Point(int x, int y,int xan, int yan,int L){
this.x=x;
this.y=y;
this.L=L;
this.xan=xan;
this.yan=yan;}
public String toString(){
return("("+x+","+y+")");
}
public int compareTo(Object ob){
Point ob1=(Point)ob;
if((x==ob1.x)&&(y==ob1.y))
return 0;
else if(L<ob1.L)
return -1;
return 1;
}

public boolean equals(Object ob){
Point ob1=(Point)ob;
if(x==ob1.x&&y==ob1.y)
return true;
return false;


}
}

Merci d'avance pour votre aide

1 réponse

KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
Premier point, normalement on devrait paramétrer la classe Comparable<E> par défaut elle compare sa valeur avec n'importe quel Object, ça se voit d'ailleurs dans la méthode compareTo(Object), en faisant ça bien tu devrais donc avoir :

public class Point implements Comparable<Point>
{
	...
}

Ensuite, ta méthode de comparaison est très compliquée, on ne sait pas du tout à quoi correspond L, xan et yan, mais de toute évidence tu devrais d'abord traiter le critère de tri principal (sur x et y) avant de t'attaquer à un éventuel critère de tri secondaire (L, xan, yan), or dans ton code

@Override
public int compareTo(Point p)
{
	return (x!=p.x) ? (x-p.x) : (y-p.y);
}

De plus, il est souvent préférable d'avoir des données consistantes, c'est à dire que l'égalité avec equals, et l'égalité compareTo==0 devraient renvoyer le même résultat, ce n'était pas le cas avec ton code, et bien que ce ne soit pas obligatoire ce serait logique dans ton cas.

Remarque : il est indispensable de vérifier que l'Object que tu compares est bien de type Point avant de faire un cast explicite qui te renverrait une exception sinon.

@Override
public boolean equals(Object obj)
{
	return (obj instanceof Point)
		&& this.compareTo((Point) obj)==0;
}

Enfin, tu parles d'utiliser un TreeSet, c'est bien, mais ta classe Point doit pouvoir être suffisamment complète pour être utilisée dans n'importe quel contexte, en particulier avec un HashSet. Pour cela il faut aussi redéfinir le hashCode afin d'optimiser les performances.

@Override
public int hashCode()
{
	return (x << 6) + y;
}
1
hasnaa-1 Messages postés 10 Date d'inscription   Statut Membre Dernière intervention  
 
merci
voila le code apres avoir suivre vos conseilles
package optimisation;
public class Point implements Comparable<Point> {
	int x;
	int y;
	int L;
	int xan;
	int yan;
	Point(int x, int y,int xan, int yan,int L)
		{
		this.x=x;
		this.y=y;
		this.L=L;
     	this.xan=xan;
     	this.yan=yan;
     	}
	public String toString(){
		return("("+x+","+y+")");	
							}
	public int compareTo(Point ob){
		if((this.x==ob.x)&&(this.y==ob.y))
			return 0;
		else if(this.L<ob.L)
			return -1;
		else return 1;
									}

	public int hashCode()
	{
		return(x+y);
	}
	public boolean equals(Point o){
		if(this.x==o.x&&this.y==o.y)
					return true;
		else return false;
		
		
	}
	

}

mais j ai encore le meme probleme
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
Parce que tu ne fais pas comme j'ai fait !

public int compareTo(Point ob){
		if((this.x==ob.x)&&(this.y==ob.y))
			return 0;
		else if(this.L<ob.L)
			return -1;
		else return 1;
									}

Ca c'est le même code que celui que tu avais fait avant, mais il est faux, il ne prend pas en compte tous les cas de ton premier critère de tri (x et y), il passe immédiatement au second critère de tri (L) qui n'a rien à faire là.

De plus, mais là encore c'est parce que tu ne fais pas ce que je dis, ta méthode equals doit prendre un Object en paramètre, sinon ce n'est pas une redéfinition mais une surcharge ce qui n'a pas du tout le même effet !
0
hasnaa-1 Messages postés 10 Date d'inscription   Statut Membre Dernière intervention  
 
je crois que l'argument de compareTo peut ne pas etre de type Object car j'ai utilise
Comparable<Point>
et pour le faite que j'utilise le L comme parametre dans compareTo :
c'est parceque j aurai besoin de ce resultat après dans mon programme complet
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
"je crois que l'argument de compareTo peut ne pas etre de type Object car j'ai utilise
Comparable<Point> "

Je parlais de l'argument de la méthode equals qui est elle toujours un Object !

"pour le faite que j'utilise le L comme parametre dans compareTo :
c'est parceque j aurai besoin de ce resultat après dans mon programme complet"

Que tu t'en serve plus tard ou non ne change rien avec la méthode de comparaison, certes tu peux t'en servir comme critère de tri secondaire au cas où il y ait égalité des x et des y, mais s'il n'y a pas cette égalité c'est sur les x et les y que tu dois faire la comparaison, or toi tu considères que soit x et y sont égaux et les objets sont égaux, soient c'est L qui détermine si les objets sont inférieur ou supérieur, tu ne traites jamais les cas pourtant fondamentaux, où les x et y sont plus petits ou plus grands. C'est pour ça que ça ne marche, tes comparaisons ne sont pas logiques !
0