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 :

Problème de tri d'une List


Sujet :

Collection et Stream Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    64
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 64
    Par défaut Problème de tri d'une List
    Bonsoir à tous,

    Je galère quelque peu avec le tri d'une collection... J'ai une classe MaClasse qui contient différentes variables de classe. Je récupère en base de données une liste d'objets MaClasse et je souhaiterais que cette liste soit triée selon l'une des variables de cette classe. Je précise tout de suite que je ne peux pas faire le tri directement en SQL, cette donnée étant calculée via des règles de gestion trop complexes à coder dans la requête.

    La classe MaClasse implémente Comparable et redéfinit donc la méthode compareTo(), ainsi que la méthode equals(). Voir l'extrait de code ci-dessous:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    public class MaClasse implements Comparable {
    	private final char type;
     
    	public final char getType() {
    		return this.type;
    	}
     
    	public final void setType(final char newType) {
    		this.type = newType;
    	}
     
    	@Override
    	public final int compareTo(final MaClasse other) {
    		final char thisType = this.getType();
    		final char otherType = other.getType();
    		int result = 0;
     
    		if(this.equals(other)) {
    			result = 0;
    		} else if(thisType == 'P') {
    			result = 1;
    		} else if(thisType == 'S') {
    			if(otherType == 'P') {
    				result = -1;
    			} else if(otherType == 'A') {
    				result = 1;
    			}
    		} else if(thisType == 'A') {
    			if(otherType == 'P' || otherType == 'S') {
    				result = -1;
    			} else {
    				result = 0;
    			}
    		}
     
    		return result;
    	}
     
    	@Override
    	public final boolean equals(final Object other) {
    		Boolean equals = null;
     
    		if(other instanceof MaClasse) {
    			final MaClasse tmp = (MaClasse) other;
     
    			equals = (this.getType() == tmp.getType());
    		} else {
    			equals = Boolean.FALSE;
    		}
     
    		return equals;
    	}
    }
    Le tri doit se faire de la manière suivante:
    1. d'abord les objets dont le type est 'P'
    2. ensuite les objets dont le type est 'S'
    3. enfin les objets dont le type est 'A'
    Je fais ce tri via la méthode statique Collections.sort(). A l'exécution, ma liste n'est jamais triée comme il le faudrait, les objets apparaissent dans le désordre !!! Pourtant en debug, la méthode compareTo() me retourne bien les valeurs adéquates...

    Aurais-je loupé quelque chose ??? Si quelqu'un a la moindre idée sur le pourquoi du comment, je suis preneur ! D'avance merci

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 764
    Par défaut
    Citation Envoyé par papyreno Voir le message
    Je fais ce tri via la méthode statique Collections.sort(). A l'exécution, ma liste n'est jamais triée comme il le faudrait, les objets apparaissent dans le désordre !!!
    Montre le code où tu tries puis affiches ta liste...
    Il est possible que le tri se soit effectué correctement, mais que tu ne parcoures pas correctement la liste au moment de l'affichage.

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Par défaut
    Est-ce le vrai code ? Parce qu'il me semble bien que cette classe bien simplifiée ne compilera pas.

    Pour ta méthode compareTo, je la trouve bien complexe pour ce qu'elle fait, sachant qu'il peut y avoir davantage d'erreurs avec un nombre plus important de lignes. Est-ce que ce code simplifié ne t'aidera pas ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    private static final String PSA = "PSA";
     
    public boolean compareTo (MaClasse that) {
      return PSA.indexOf(that.type) - PSA.indexOf(this.type);
    }
    Autre chose à vérifier : est-ce que l'appel à Collections.sort() se fait bien sur l'instance que tu désires renvoyer, pas un clone ou quelque chose comme ça ?

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    64
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 64
    Par défaut
    @Astartee: Voici le code où la liste est triée puis parcourue:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    final StringBuffer sbResultat = new StringBuffer();
     
    // this.getEnregistrementsMaClasse() est une ArrayList
    if(this.getEnregistrementsMaClasse() != null
    		&& this.getEnregistrementsMaClasse().size() > 0) {
    	Collections.sort(this.getEnregistrementsMaClasse());
     
    	final Iterator<MaClasse> itMaClasse = this.getEnregistrementsMaClasse().iterator();
    	MaClasse monObjet = null;
     
    	while(itMaClasse.hasNext()) {
    		monObjet = itMaClasse.next();
     
    		sbResultat.append(System.getProperty("line.separator"))
    			.append(monObjet.toString());
    	}
    }
    Pour info, le but est de générer un fichier texte contenant les infos du StringBuffer sbResultat.

    @dingoth: Ce n'est pas le vrai code, je ne pense pas que mon chef apprécierait que le code de notre application se retrouve sur le net Mais la classe que je vous ai présentée est fortement inspirée de la classe réelle, qui elle passe à la compilation.
    Je vais essayer avec ta méthode compareTo(), qui effectivement est beaucoup plus simple que la mienne !

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 764
    Par défaut
    Citation Envoyé par papyreno Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    // this.getEnregistrementsMaClasse() est une ArrayList
    if(this.getEnregistrementsMaClasse() != null
    		&& this.getEnregistrementsMaClasse().size() > 0) {
    	Collections.sort(this.getEnregistrementsMaClasse());
     
    	final Iterator<MaClasse> itMaClasse = this.getEnregistrementsMaClasse().iterator();
    	[...]
    	}
    }
    Lorsque tu appelles getEnregistrementsMaClasse(), tu récupères bien toujours directement le même objet sans lui appliquer de traitement (du genre : {return this.enregistrements;}), et pas par exemple une nouvelle liste construite dans la fonction ?
    Et dans ce cas, pourquoi appeler "this.getEnregistrementsMaClasse()" et pas directement l'objet renvoyé par cette fonction (du genre "enregistrements") ?

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    64
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 64
    Par défaut
    Citation Envoyé par Astartee Voir le message
    Lorsque tu appelles getEnregistrementsMaClasse(), tu récupères bien toujours directement le même objet sans lui appliquer de traitement (du genre : {return this.enregistrements;}), et pas par exemple une nouvelle liste construite dans la fonction ?
    Non le getter ne fait aucun traitement sur la liste, juste un return bête et méchant.
    Citation Envoyé par Astartee Voir le message
    Et dans ce cas, pourquoi appeler "this.getEnregistrementsMaClasse()" et pas directement l'objet renvoyé par cette fonction (du genre "enregistrements") ?
    Pourquoi j'utilise cet accesseur ? Euh... Parce que j'ai toujours fait comme ça

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    64
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 64
    Par défaut
    En attendant de résoudre ce problème, je vais faire un truc "crade"... Un getter qui ne retournera que les enregistrements de type P, un pour les types S et un pour les types A. Pas très satisfaisant intellectuellement mais bon...

    Merci à vous 2 pour votre aide !

  8. #8
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Par défaut
    si je peux te conseiller, fais tout de même ceci : je me méfie malgré tout de this.getEnregistrementsMaClasse()... Est-ce toi qui a écrit ce getter ? As-tu accès aux sources de ce getter pour t'assurer que c'est bien un return tout simple ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    final StringBuilder sbResultat = new StringBuilder();
     
    List<MaClasse> mesEnregistrements = this.getEnregistrementsMaClasse();
    if (mesEnregistrements != null && mesEnregistrements.size() > 0) {
    	Collections.sort(mesEnregistrements);
     
    	String ln = System.getProperty("line.separator");
    	for (MaClasse monObjet : mesEnregistrements) {
    		sbResultat.append(ln).append(monObjet);
    	}
    }

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    64
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 64
    Par défaut
    @dingoth: oui c'est moi qui ait écrit ce getter, je suis sûr et certain qu'il ne fait qu'un return tout simple

    @Astartee: non je n'ai pas d'autres types d'enregistrements à gérer, seulement, P, S et A. Je viens d'essayer avec ta méthode compareTo() et ... ça marche !!! Il semblerait donc que je sois un boulet et que mon problème venait tout simplement du fait que j'avais fait mon tri à l'envers... La fatigue, c'est le mal !!!

    Un grand merci à vous deux pour votre aide précieuse !!!

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

Discussions similaires

  1. Problème de tri dans une liste
    Par zatura dans le forum Débuter avec Java
    Réponses: 9
    Dernier message: 26/10/2011, 19h05
  2. Tri d'une liste d'objet CObList
    Par cjacquel dans le forum MFC
    Réponses: 1
    Dernier message: 13/07/2005, 13h50
  3. Réponses: 4
    Dernier message: 16/06/2005, 15h37
  4. [TRI] tri d'une list provenant de LabelValueBean
    Par Canou dans le forum Struts 1
    Réponses: 6
    Dernier message: 20/09/2004, 14h55
  5. tri d'une liste
    Par Guigui_ dans le forum Langage
    Réponses: 4
    Dernier message: 09/01/2003, 18h08

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