Implementation de comparable ne marche pas

Fermé
hasnaa-1 Messages postés 10 Date d'inscription lundi 20 mai 2013 Statut Membre Dernière intervention 3 janvier 2014 - Modifié par hasnaa-1 le 17/06/2013 à 17:11
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 - 17 juin 2013 à 21:16
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 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
Modifié par KX le 17/06/2013 à 18:58
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 lundi 20 mai 2013 Statut Membre Dernière intervention 3 janvier 2014
17 juin 2013 à 19:29
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 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
17 juin 2013 à 20:05
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 lundi 20 mai 2013 Statut Membre Dernière intervention 3 janvier 2014
17 juin 2013 à 21:07
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 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
Modifié par KX le 17/06/2013 à 21:16
"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