Stress sur un TreeSet ! objets non equals removés

Stress sur un TreeSet ! objets non equals removés - Java - Programmation

Marsh Posté le 07-01-2004 à 02:06:33    

Là y'a un truc qui m'échappe.
 
J'ai un TreeSet dans lequel je mets des objets Xyz qui implementent Comparable.
Mon implémentation de Comparable est pas "nickel", dans la mesure ou elle n'est pas cohérente avec le equals(), mais d'après la javadoc c'est un comportement acceptable meme si non recommandé.
 
Vla t'y pas que j'ai deux une instance de Xyz, qu'on va appeller A et B.  
 
A.compareTo(B) renvoie 0, mais A.equals(B) renvoie false.
 
je prend mon set, je fais
 
set = new TreeSet();
set.add(A);
set.remove(B);
 
et vlan, mon set est vide.
 
 :heink:


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 07-01-2004 à 02:06:33   

Reply

Marsh Posté le 07-01-2004 à 02:46:47    

[:blueflag]
 
>> benou la petite bite soi disant, elle t'emmerde!!!!

Reply

Marsh Posté le 07-01-2004 à 02:56:27    

je t'ai fait un exemple vite fait
 

Code :
  1. public class MyInteger extends java.lang.Number implements java.lang.Comparable {
  2. private int value;
  3. public MyInteger(int n) {
  4. this.value=n;
  5. }
  6. /* (non-Javadoc)
  7.  * @see java.lang.Number#intValue()
  8.  */
  9. public int intValue() {
  10.  // TODO Auto-generated method stub
  11.  return 0;
  12. }
  13. /* (non-Javadoc)
  14.  * @see java.lang.Number#longValue()
  15.  */
  16. public long longValue() {
  17.  // TODO Auto-generated method stub
  18.  return 0;
  19. }
  20. /* (non-Javadoc)
  21.  * @see java.lang.Number#floatValue()
  22.  */
  23. public float floatValue() {
  24.  // TODO Auto-generated method stub
  25.  return 0;
  26. }
  27. /* (non-Javadoc)
  28.  * @see java.lang.Number#doubleValue()
  29.  */
  30. public double doubleValue() {
  31.  // TODO Auto-generated method stub
  32.  return 0;
  33. }
  34. /* (non-Javadoc)
  35.  * @see java.lang.Comparable#compareTo(java.lang.Object)
  36.  */
  37. public int compareTo(Object arg0) {
  38.  // TODO Auto-generated method stub
  39.  if(this==arg0) return 0;
  40.  else return 1;
  41. }
  42. }


 

Code :
  1. public class Forum {
  2. public static void main(String[] args) {
  3. /*
  4. TreeSet T = new TreeSet();
  5. Integer N = new Integer(3);
  6. Integer N2 = new Integer(3);
  7. T.add(N);
  8. T.remove(N2);
  9. System.out.println(N.compareTo(N2));
  10. System.out.println(T.contains(N2));
  11. System.out.println(T.remove(N2));
  12. System.out.println(T.isEmpty());
  13. */
  14. TreeSet T = new TreeSet();
  15. MyInteger N = new MyInteger(1337);
  16. MyInteger N2 = new MyInteger(1337);
  17. T.add(N);
  18. T.remove(N2);
  19. System.out.println(T.isEmpty());
  20. }
  21. }


 
voila en fait le prob c'est que le remove se fait en fonction du résulat de compareTo et pas des adresses donc chez toi comme A et B ont 0 comme résultat de compareTo bah il va supprmier A meme si tu lui demandes de supprimer B
pouet :p


Message édité par dlxzap le 07-01-2004 à 02:57:37
Reply

Marsh Posté le 07-01-2004 à 03:00:06    

ben... oui.
c'est nul.
il pourrait checker le equals ce porc.


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 07-01-2004 à 03:06:02    

ouaip
je ferais bien une implémentation perso :x

Reply

Marsh Posté le 07-01-2004 à 03:06:54    

dlxZap a écrit :

ouaip
je ferais bien une implémentation perso :x

non mais doit y'avoir une explication spa possible...
 
là j'ai encore mieux: mon objet n'implemente plus Comparable, he ben vlan il se viande en essayant de caster des Comparable :heink:
 
 
(edit: Comparable par Comparator [:aloy])


Message édité par the real moins moins le 07-01-2004 à 03:10:41

---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 07-01-2004 à 03:14:42    

bon ben

Citation :

Note that the ordering maintained by a set (whether or not an explicit comparator is provided) must be consistent with equals if it is to correctly implement the Set interface. (See Comparable  or Comparator for a precise definition of consistent with equals.) This is so because the Set interface is defined in terms of the equals operation, but a TreeSet instance performs all key comparisons using its compareTo (or compare) method, so two keys that are deemed equal by this method are, from the standpoint of the set, equal. The behavior of a set is well-defined even if its ordering is inconsistent with equals; it just fails to obey the general contract of the Set interface.

dans mon cul, quoi.


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 07-01-2004 à 09:41:13    

the real moins moins a écrit :

A.compareTo(B) renvoie 0, mais A.equals(B) renvoie false.
 
je prend mon set, je fais
 
set = new TreeSet();
set.add(A);
set.remove(B);
 
et vlan, mon set est vide.
 
 :heink:  


:/ bha, c'est normal, [:spamafote]
 
Si tu veux pas que ca fasse ca, tu te débrouilles pour que ton coparable ne retourne jamais 0, ou bien mieux, tu utilises un Comparator qui utilie le comparable mais qui retourne -1 dans le cas où le compareTo retourne 0 ...


Message édité par benou le 07-01-2004 à 09:41:58
Reply

Marsh Posté le 07-01-2004 à 09:41:44    

darklord a écrit :


>> benou la petite bite soi disant, elle t'emmerde!!!!


peut être mais elle s'explique pas beaucoup  :kaola:

Reply

Marsh Posté le 07-01-2004 à 09:45:25    

the real moins moins a écrit :

Là y'a un truc qui m'échappe.
 
J'ai un TreeSet dans lequel je mets des objets Xyz qui implementent Comparable.A.compareTo(B) renvoie 0, mais A.equals(B) renvoie false.


et ca c'est vraiment très mal ! Problème de design !
 
Si tu veux pouvoir ordonner tes instances mais qu'il ne s'agit pas d'un ordre naturel, il vaux largement mieux fournir un Comparator que d'implémenter Comparable. En inner classe static par exemple ou dans une classe à côté. C'est ce qu'ils ont fait pour String par exemple : y a l'ordre naturel et une instance static de Comparator qui permet de trier en case non-sensitive.

Reply

Marsh Posté le 07-01-2004 à 09:45:25   

Reply

Marsh Posté le 07-01-2004 à 13:10:55    

benou a écrit :


et ca c'est vraiment très mal ! Problème de design !
 
Si tu veux pouvoir ordonner tes instances mais qu'il ne s'agit pas d'un ordre naturel, il vaux largement mieux fournir un Comparator que d'implémenter Comparable. En inner classe static par exemple ou dans une classe à côté. C'est ce qu'ils ont fait pour String par exemple : y a l'ordre naturel et une instance static de Comparator qui permet de trier en case non-sensitive.

Je vote +1 (sauf qu'une classe n'est pas inner si elle est static, elle est simplement nested JLS 8.1.2)  
 
En fait il y a confusion entre classe et role dans le domaine de l'objet actuel. En gros un objet peut avoir plusiseurs rôles, dont un principal, c'est vis-à-vis de ce rôle qu'on va définir equals, hashCode et compareTo. Une classe peut avoir des rôles secondaires, qu'on exploitera par des composants "branchables" (pluggables).
 
Hélas, en java la modularité des collections est assez limitée, les seuls point de branchement est Comparator pour les TreeSet et les clefs de Map.
 
mais dans d'autres frameworks, on peut externaliser la fonction de hachage, l'égalité, les clef pour les maps (c'est aussi le cas en java) ou avoir une clef interne à la classe (ainsi, par ex., le map va chercher tout seul le nom d'une personne dans l'objet pour l'utilisr comme clef) et les fonctions de comparaison.


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 07-01-2004 à 13:21:01    

nraynaud a écrit :

Je vote +1 (sauf qu'une classe n'est pas inner si elle est static, elle est simplement nested JLS 8.1.2)


:jap: je ne connaissais pas la différence de signification de ces 2 mots
 
Hélas, en java la modularité des collections est assez limitée, les seuls point de branchement est Comparator pour les TreeSet et les clefs de Map.
mais dans d'autres frameworks, on peut externaliser la fonction de hachage, l'égalité, les clef pour les maps[/citation]
 
Pour celà tu peux faire des inner classes (qui seront ajoutées dans les collections à la place de l'objet lui même) et qui définissent les méthodes hashCode, equals et éventuellement compareTo.
 
Mais il est vrai que ce méchanisme n'est pas présent de base dans le framework Collection mais il est facilement implémentable (2 interfaces + surcharge des classes du framework).


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 07-01-2004 à 13:37:23    

benou a écrit :


:jap: je ne connaissais pas la différence de signification de ces 2 mots
 
Pour celà tu peux faire des inner classes (qui seront ajoutées dans les collections à la place de l'objet lui même) et qui définissent les méthodes hashCode, equals et éventuellement compareTo.
 
Mais il est vrai que ce méchanisme n'est pas présent de base dans le framework Collection mais il est facilement implémentable (2 interfaces + surcharge des classes du framework).

1) je pensais que tu connaissait mais j'ai joué le lourd comme picure de rappel pour un peu tout le monde.
 
2) oui, mais le problème est pris à l'envers dans ce cas.  
Tentage d'explication (pas forcément pour toi d'ailleur) : tu ne files pas à la collection l'objet mais un truc représentant un de ses rôles. à la sortie de la collection, il va falloir faire une opération pour récupérer l'objet. Alors que customiser la collection une fois pour toutes n'engage pas les clients de la collection. en plus ça ne fonctionne que pour les classes et pas pour les interface.
d'autre part, l'abus d'allocation de petits objets assassine le garbage collector.


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 07-01-2004 à 14:26:21    

Bha oui je sais, c'est de la bidouille ... mais si on considère que le framework collection contient des briques de base, c'est pas illogique de vouloir étendre ces fonctionnalités de base.
 
Quand à la remarque sur le GC ... ce n'est certainement pas une chose à prendre en compte quand on cherche un design propre ...


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 07-01-2004 à 14:33:06    

benou a écrit :

Quand à la remarque sur le GC ... ce n'est certainement pas une chose à prendre en compte quand on cherche un design propre ...

d'ailleur on devrait peut-être éliminer Singleton et Flyweight du vocabulaire de patterns.


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 07-01-2004 à 16:36:58    

benou a écrit :


et ca c'est vraiment très mal ! Problème de design !


http://java.sun.com/j2se/1.4.2/doc [...] ng.Object)

Citation :

It is strongly recommended, but not strictly required that (x.compareTo(y)==0) == (x.equals(y)). Generally speaking, any class that implements the Comparable interface and violates this condition should clearly indicate this fact. The recommended language is "Note: this class has a natural ordering that is inconsistent with equals."


 
autrement dit, c'était expressement que ma compareTo n'était pas "synchro" avec mon equals.
je savais pas encore que cet idiot de TreeSet me ferait pas un equals avant de virer mon objet !
 
 
edit: le not etait en italique mais comme tout est italique dans une citation (c'est nouveau?), je l'ai mis en gras :o


Message édité par the real moins moins le 07-01-2004 à 16:39:39

---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 07-01-2004 à 17:30:50    

Dans un set il n'est pas possible de mettre plusieures fois le même élément non ? Avec un comparateur comme ça, du point de vue du set les 2 objets sont egaux. Et par consequence, il ne devrait pas être possible de mettre à la fois A et B.

Reply

Marsh Posté le 07-01-2004 à 18:39:03    

justement, on pinaille sur "le même élément" là.


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 07-01-2004 à 19:28:36    

the real moins moins a écrit :


It is strongly recommended, but not strictly required that  


 
et alors ??? on te dit que c'est pas recommandé et toi tu t'empresse de le faire... T'étonnes pas qu'on te dise que t'as un problème de design [:spamafote]
 
Moi je trouverai illogique que le TreeSet se serve de equals alors qu'on lui passe un Comparator explicitement. Ca aurait même aucun sens ...
 
et le fait que ce soit pas "required" ca veut dire que ton programme pourra s'executer pas qu'il va s'executer logiquement ...


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 07-01-2004 à 21:05:14    

"Effective STL"  Item 19: Understand the difference between equality and equivalence.  
 
Avant, j'aurais conseillé ce livre a toute personne faisant du C++. Grace à ce thread je vais aussi le conseiller à toute personne faisant du Java :D

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed