IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Collection et Stream Java Discussion :

ordre et unicite d'un TreeSet


Sujet :

Collection et Stream Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Décembre 2003
    Messages
    65
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Décembre 2003
    Messages : 65
    Par défaut ordre et unicite d'un TreeSet
    bonjour,

    j'ai un ensemble d'objet auquels sont affecte des scores et j'ai besoin d'une structure qui me permette d'assurer l'unicite des objets et de les ordonner. Par contre, l'unicite porte sur l'objet et l'ordonancement porte sur le score.

    J'ai donc cree une classe qui contient l'objet et son score :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    class element {
        private Object objet;
        private double score;
     
        public boolean equals(Object o) {
            return objet.equals(((element)o).getObjet());
        }
    }
    et j'ai voulu utiliser un TreeSet en redefinissant les methode equals (pour que l'unicite porte sur l'objet) et en donnant un comparateur (pour que le tri se fasse sur les scores) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public class MaClass {
        Set set = new TreeSet<element>(new Comparator<element>() {
            public int compare(element elt1,element elt2) {
                public int compare(element elt1,element elt2) {
                    double diff = elt1.getScore() - elt2.getScore();
                    return (int)(diff+Math.signum(diff)*0.5);
                }
            });
        }
    }
    Seulement, la javadoc specifie que la methode compareTo doit etre coherente avec la methode Equals, ce qui ne serait pas le cas!

    j'aimerais donc savoir comment avoir une structure qui me permettent l'avoir l'unicite et un ordonnancement qui portent sur des attributs differents.

  2. #2
    Membre expérimenté
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Mars 2002
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Mars 2002
    Messages : 192
    Par défaut
    Il n'y a aucune raison pour que cela ne fonctionne pas.
    Pour ce qui est de la javadoc, elle ne dit pas que la méthode compare (ou compareTo si tu implémentes Comparable) doit être cohérente avec la méthode equals, elle dit qu'en général elle doit l'être.
    It is generally the case, but not strictly required that (compare(x, y)==0) == (x.equals(y)). Generally speaking, any comparator that violates this condition should clearly indicate this fact. The recommended language is "Note: this comparator imposes orderings that are inconsistent with equals."
    Tu as tout a fait le droit de faire ce que tu veux faire.

    Matthieu

  3. #3
    Rédacteur

    Profil pro
    Inscrit en
    Juin 2003
    Messages
    4 184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 184
    Par défaut
    dans ta méthode equals, il faut tester d'abord si la classe est une instance de ton elemnt..sinon tu risque d'avoir un classCastException ...
    En plus, tu te base sur la méthode equals de la classe objet, qui copare juste les réferences et pas les valeurs..faut enrichir ta méthode equals.
    le contrat qu'elle doit respecter est:

    - x.equals(y)=true ->y.equals(x)=true
    - x.equals(y) et x.equals(z)=true -> x.equals(z)=true
    - x.equals(x) = true
    - x.equals(y) retourne la meme valeur quelque soit le context de l'execution ..
    - x.equals(null) retourne toujoutd false

  4. #4
    Membre expérimenté
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Mars 2002
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Mars 2002
    Messages : 192
    Par défaut
    Citation Envoyé par Sniper37
    dans ta méthode equals, il faut tester d'abord si la classe est une instance de ton elemnt..sinon tu risque d'avoir un classCastException ...
    C'est peut être juste un aperçu du equals qu'il a écrit.
    Citation Envoyé par Sniper37
    En plus, tu te base sur la méthode equals de la classe objet, qui copare juste les réferences et pas les valeurs..faut enrichir ta méthode equals.
    Ben s'il référence des objets qui surchargent equals ce sera le equals de ces objets qui sera appelé. Mets des String dans les elements et ce sera une égalité de String qui sera effectuée.

    Matthieu

  5. #5
    Membre averti
    Inscrit en
    Décembre 2003
    Messages
    65
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Décembre 2003
    Messages : 65
    Par défaut
    Citation Envoyé par McFoggy
    C'est peut être juste un aperçu du equals qu'il a écrit.
    c'est ca!
    Citation Envoyé par McFoggy
    Ben s'il référence des objets qui surchargent equals ce sera le equals de ces objets qui sera appelé. Mets des String dans les elements et ce sera une égalité de String qui sera effectuée.
    oui c'est aussi ca! en fait ma classe element est generique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public class element<T> {
        private T elt;
        public boolean equals(Object o) {
            return elt.equals( ((element)o).getElt() );
        }
    }

  6. #6
    Membre averti
    Inscrit en
    Décembre 2003
    Messages
    65
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Décembre 2003
    Messages : 65
    Par défaut
    Citation Envoyé par McFoggy
    Il n'y a aucune raison pour que cela ne fonctionne pas.
    Pour ce qui est de la javadoc, elle ne dit pas que la méthode compare (ou compareTo si tu implémentes Comparable) doit être cohérente avec la méthode equals, elle dit qu'en général elle doit l'être.
    It is generally the case, but not strictly required that (compare(x, y)==0) == (x.equals(y)). Generally speaking, any comparator that violates this condition should clearly indicate this fact. The recommended language is "Note: this comparator imposes orderings that are inconsistent with equals."
    Tu as tout a fait le droit de faire ce que tu veux faire.

    Matthieu
    sur la javadoc des treeset, je lis
    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.
    Et j'ai besoin de respecter l'interface Set pour l'unicite porte sur les objets pas sur les scores

  7. #7
    Membre expérimenté
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Mars 2002
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Mars 2002
    Messages : 192
    Par défaut
    Citation Envoyé par mobi38
    sur la javadoc des treeset, je lis
    Désolé j'avais regardé que Comparator et Comparable.

    Pour ce qui en est de ton problème, si tu veux respecter complètement l'API de Set (à noter que l'utilisation de equals et de compare différent de equals engendre aussi une collection de type Set au sens unicite des objets) et donc utiliser tes instances d'objets au travers de l'interface Set et de sa méthode iterator, je pense que le mieux serait de surcharger une implémentation de Set, HashSet par exemple et de surcharger iterator pour retourner un iterateur qui aura ordonné les éléments sur l'index.

    Si tu trouves d'autres solutions n'hésites surtout pas à les poster cela peut être interressant.

    Matthieu

  8. #8
    Membre averti
    Inscrit en
    Décembre 2003
    Messages
    65
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Décembre 2003
    Messages : 65
    Par défaut
    De toute maniere, j'etais obliger d'avoir deux structures de donnees.

    La solution que j'ai trouvee est d'avoir :
    - une HashMap dont les cles sont les objets et les valeurs les instances d'element correspondantes
    - un TreeMap ou les cles sont les scores et les valeurs des listes de molecules qui ont ce score

    cette solution me permet de
    - avoir les caracteristiques d'un objet (score, etc...)
    - avoir l'objet de score le plus faible et de pouvoir le supprimer
    - assurer l'unicite des objets (les cle d'un HashMap sont unique)
    - et tout ca en un temps <O(n)

    commentaires?

  9. #9
    Membre expérimenté
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Mars 2002
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Mars 2002
    Messages : 192
    Par défaut
    Citation Envoyé par mobi38
    commentaires?
    Ben aucuns si ça répond à ton problème. En effet l'nconvéniant de surcharger Iterator ou autre induisait un tri, ce qui pouvait ne pas être super efficace si tu as beaucoups d'éléments. Tant mieux si tu as ta solution, bon courage pr la suite alors...

    Matthieu

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. TreeSet perso avec ordre modifiable après instanciation
    Par gabz57 dans le forum Collection et Stream
    Réponses: 0
    Dernier message: 28/07/2012, 23h28
  2. ORDER BY dans un ordre inhabituel
    Par Riam dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 21/03/2003, 13h29
  3. Question : ordre des bits ?
    Par Choupi dans le forum C
    Réponses: 3
    Dernier message: 11/02/2003, 06h22
  4. Ordre de parcours de l'arbre...
    Par Sylvain James dans le forum XML/XSL et SOAP
    Réponses: 3
    Dernier message: 01/12/2002, 18h41
  5. [] Tri d'un tableau par ordre alphabétique
    Par cafeine dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 17/09/2002, 08h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo