1. #1
    Futur Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    mars 2017
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : mars 2017
    Messages : 9
    Points : 7
    Points
    7

    Par défaut Liste d'objets fusionnés affichés en double

    Bonjour,

    soit une liste, cette liste d'objets <HistoriqueChargement> comporte parfois des objets dont certains ont un attribut identique.
    Si cet attribut "code" est donc identique, je souhaite "fusionner" ces objets dans une nouvelle liste.

    Cependant, les objets ainsi fusionnés de ma nouvelle liste s'affiche en double. Si vous pouviez m'expliquer mon erreur.

    Mon code :
    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
    List<HistoriqueFichierFusionne> laNouvelleListe = new ArrayList<HistoriqueFichierFusionne>();
     
            HistoriqueChargement historiqueChargementPrecedent = null;
     
            for (HistoriqueChargement historiqueChargement : laListeDesHistoriqueChargement)
            {
     
                HistoriqueFichierFusionne leNouvelHistorique = new HistoriqueFichierFusionne();
                for (int i = 0; i < laListeDesHistoriqueChargement.size(); i++)
                {
     
                    if (historiqueChargementPrecedent == null)
                    {
                        historiqueChargementPrecedent = laListeDesHistoriqueChargement.get(0);
     
                    }
                    else
                    {
     
                        historiqueChargementPrecedent = laListeDesHistoriqueChargement.get(i);
     
                    }
     
                    if (historiqueChargement.getCode().compareTo(historiqueChargementPrecedent.getCode()) == 0)
                    {
     
                        leNouvelHistorique.setCode(historiqueChargement.getCode());
                        leNouvelHistorique.setAnnee(leFormulaire.getLesCriteresRechercheSuiviInterface().getAnneeRecherchee());
                        if (historiqueChargement.getLeTypeIntegrationFichier().equals(TypeIntegrationFichier.PREVISIONNELLE))
                        {
                            leNouvelHistorique.setDateIntegrationPrevisionnelle(historiqueChargement.getDateIntegration());
                        }
                        if (historiqueChargement.getLeTypeIntegrationFichier().equals(TypeIntegrationFichier.DEFINITIVE))
                        {
                            leNouvelHistorique.setDateIntegrationDefinitive(historiqueChargement.getDateIntegration());
                        }
                        if (historiqueChargementPrecedent.getLeTypeIntegrationFichier().equals(
                            TypeIntegrationFichier.PREVISIONNELLE))
                        {
                            leNouvelHistorique.setDateIntegrationPrevisionnelle(historiqueChargementPrecedent.getDateIntegration());
                        }
                        if (historiqueChargementPrecedent.getLeTypeIntegrationFichier().equals(TypeIntegrationFichier.DEFINITIVE))
                        {
                            leNouvelHistorique.setDateIntegrationDefinitive(historiqueChargementPrecedent.getDateIntegration());
                        }
                    }
     
                }
     
                laNouvelleListe.add(leNouvelHistorique);
            }
    Sortie en console :

    976 2017 2017-05-01 08:00:00.0 2017-12-01 08:00:00.066
    976 2017 2017-05-01 08:00:00.0 2017-12-01 08:00:00.066
    B21 2017 2017-05-01 08:00:00.0 2017-12-01 08:00:00.008
    B21 2017 2017-05-01 08:00:00.0 2017-12-01 08:00:00.008


    Par avance, je vous remercie de votre aide

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java/Eclipse RCP
    Inscrit en
    septembre 2009
    Messages
    11 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java/Eclipse RCP
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2009
    Messages : 11 028
    Points : 26 297
    Points
    26 297
    Billets dans le blog
    2

    Par défaut

    Salut,

    Tu n'exclus de la comparaison dans la deuxième boucle l'élément lui-même.

    Supposons qu'on ait cette liste (A, B, C), tel que code de A est égale à code de C (d'ailleurs pourquoi faire un compareTo()==0, alors qu'un equals est plus simple ?), donc d'après ce que je comprends de ton code, à fusionner. Mais avec ton double parcourt tu vas comparer :

    • A avec A
    • A avec B
    • A avec C
    • B avec A
    • B avec B
    • B avec C
    • C avec A
    • C avec B
    • C avec C


    Si A comparé à C donne une fusion parce que code de A égal code de C, alors forcément C comparé à A va le faire aussi. Tu auras donc deux "nouvelhistorique" identiques (enfin pas toujours forcément identique selon l'algo de fusion) dont l'un est le résultat de la fusion de A et C et l'autre de C et A.


    A noter, que s'il n'y a aucun doublon, tu ajoutes quand même une fusion à la liste à la fin, puisque tu compares un élément forcément avec lui-même, qui donc est forcément égal à lui-même, donc va se fusionner à lui-même. Si cet élément a aussi un doublon, comme tu utilises la même instance (créée avant d'entrer dans la sous-boucle), ça ne pose pas de souci si la fusion est commutative (A fusionné avec B donne la même chose que B fusionné avec A). Mais si un élément n'a pas de doublon tu le retrouves quand même dans la liste de fusion à la fin. Mais c'est peut-être voulu.

    Il y a différentes techniques par parcours pour résoudre ce problème de dédoublonnage et de fusion, mais le plus simple est encore d'utiliser un regroupement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Map<TypeDuCode,List<HistoriqueChargement >> map =  list.stream().collect(Collectors.groupingBy(HistoriqueChargement::getCode));
    Tu obtiens une map telle que les valeurs sont les listes des éléments qui ont le même code. Tu n'a plus qu'a parcourir le map.values() pour fusionner les éléments entre eux comme tu le souhaites.


    En outre, je ne sais pas pourquoi tu fais ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    if (historiqueChargementPrecedent == null)
                    {
                        historiqueChargementPrecedent = laListeDesHistoriqueChargement.get(0);
     
                    }
                    else
                    {
     
                        historiqueChargementPrecedent = laListeDesHistoriqueChargement.get(i);
     
                    }
    Le seul moment ou historiqueChargementPrecedent est null, c'est au tout début, quand i vaut 0.
    Donc autant faire simplement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
                        historiqueChargementPrecedent = laListeDesHistoriqueChargement.get(i);
     
                    }
    L'expression "ça marche pas" ne veut rien dire. Indiquer l'erreur, et/ou les comportements attendu et obtenu, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    mars 2017
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : mars 2017
    Messages : 9
    Points : 7
    Points
    7

    Par défaut Liste d'objets fusionnés affichés en double

    Bonjour,

    Merci d'avoir pris le temps d'analyser ma demande et pour tes explications très claires.
    Effectivement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    historiqueChargementPrecedent = laListeDesHistoriqueChargement.get(i);
    suffit pleinement, et equals() à la place de compareTo() est plus logique et simple.

    L'affichage des objets sans "doublon" dans la liste est effectivement voulu.

    Pour ce qui est de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Map<TypeDuCode,List<HistoriqueChargement>> map =  list.stream().collect(Collectors.groupingBy(HistoriqueChargement::getCode));
    eclipse m'indique : "change project compliance and jre to 1.8" et je ne peux changer de version pour diverses raisons.

    Dans ta réponse tu fais référence à différentes techniques par parcours pour résoudre ce problème de dédoublonnage et de fusion.
    Peux-tu m'en dire plus STP.

    Par avance merci et bonne journée.

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java/Eclipse RCP
    Inscrit en
    septembre 2009
    Messages
    11 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java/Eclipse RCP
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2009
    Messages : 11 028
    Points : 26 297
    Points
    26 297
    Billets dans le blog
    2

    Par défaut

    Citation Envoyé par veve25 Voir le message
    Pour ce qui est de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Map<TypeDuCode,List<HistoriqueChargement>> map =  list.stream().collect(Collectors.groupingBy(HistoriqueChargement::getCode));
    eclipse m'indique : "change project compliance and jre to 1.8" et je ne peux changer de version pour diverses raisons.
    Oui, parce que les streams sont apparus en Java 8. Pour quelle raison ne peux-tu pas changer de version ?

    Citation Envoyé par veve25 Voir le message
    Dans ta réponse tu fais référence à différentes techniques par parcours pour résoudre ce problème de dédoublonnage et de fusion.
    Peux-tu m'en dire plus STP.
    Une technique peut être de faire une double boucle du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    pour tous les éléments M de la liste 
         pour tous les éléments N de la liste situés strictement après l'élément M
                 si N est doublon de M, fusionner
         fin pour
    fin pour
    Une autre peut être de copier la liste dans un set ( new LinkedHashSet<>(list), LinkedHashSet pour conserver l'ordre dans la liste ) puis
    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
    while( !set.isEmpty() ) {
     
          Iterator iter = set.iterator()
          M = iter.next()
          iter.remove()
     
          F = new Fusion(M)
     
          while( iter.hasNext()) {
                 N = iter.next()
                 si ( N est doublon de M ) 
                            fusionner N dans F
                            iter.remove()
                fin si
          }
     
           fusions.add( F )
     
    }
    L'expression "ça marche pas" ne veut rien dire. Indiquer l'erreur, et/ou les comportements attendu et obtenu, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    mars 2017
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : mars 2017
    Messages : 9
    Points : 7
    Points
    7

    Par défaut

    Merci pour ta nouvelle réponse,

    J'ai donc opté pour LinkedHashSet et les problèmes de doublons et d'ordre sont réglés.
    Pas de changement de version car d'autres applications en cause.

    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
    Set<HistoriqueFichierFusionne> setHistoriqueFusionne = new LinkedHashSet<HistoriqueFichierFusionne>();
     
            HistoriqueChargement historiqueChargementPrecedent = null;
     
            for (HistoriqueChargement historiqueChargement : laListeDesHistoriqueChargement)
            {
     
                HistoriqueFichierFusionne leNouvelHistorique = new HistoriqueFichierFusionne();
                for (int i = 0; i < laListeDesHistoriqueChargement.size(); i++)
                {
     
                    historiqueChargementPrecedent = laListeDesHistoriqueChargement.get(i);
     
                    if (historiqueChargement.getCode().equals(historiqueChargementPrecedent.getCode()))
                    {
     
                        leNouvelHistorique.setCode(historiqueChargement.getCode());
                        leNouvelHistorique.setAnnee(leFormulaire.getLesCriteresRechercheSuiviInterface().getAnneeRecherchee());
                        if (historiqueChargement.getLeTypeIntegrationFichier().equals(TypeIntegrationFichier.PREVISIONNELLE))
                        {
                            leNouvelHistorique.setDateIntegrationPrevisionnelle(historiqueChargement.getDateIntegration());
                        }
                        if (historiqueChargement.getLeTypeIntegrationFichier().equals(TypeIntegrationFichier.DEFINITIVE))
                        {
                            leNouvelHistorique.setDateIntegrationDefinitive(historiqueChargement.getDateIntegration());
                        }
                        if (historiqueChargementPrecedent.getLeTypeIntegrationFichier().equals(
                            TypeIntegrationFichier.PREVISIONNELLE))
                        {
                            leNouvelHistorique.setDateIntegrationPrevisionnelle(historiqueChargementPrecedent.getDateIntegration());
                        }
                        if (historiqueChargementPrecedent.getLeTypeIntegrationFichier().equals(TypeIntegrationFichier.DEFINITIVE))
                        {
                            leNouvelHistorique.setDateIntegrationDefinitive(historiqueChargementPrecedent.getDateIntegration());
                        }
                    }
     
                }
     
                setHistoriqueFusionne.add(leNouvelHistorique);
     
            }
     
            List<HistoriqueFichierFusionne> laNouvelleListeHistoriqueFusionne = new ArrayList<HistoriqueFichierFusionne>();
            laNouvelleListeHistoriqueFusionne.addAll(setHistoriqueFusionne);

    Un grand merci pour ta réactivité et ton aide

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 22/02/2010, 14h05
  2. Afficher un élèment d'une liste d'objet
    Par tanguy.L dans le forum Langage
    Réponses: 5
    Dernier message: 29/01/2008, 12h09
  3. Afficher propriété d'une liste d'objet
    Par david06600 dans le forum Smarty
    Réponses: 1
    Dernier message: 26/09/2007, 15h53
  4. afficher une liste d'objets sur une page en flow.
    Par looploop dans le forum JSF
    Réponses: 1
    Dernier message: 18/09/2007, 10h54
  5. OpenDialog : augmenter la liste des objets affichés
    Par cybersam dans le forum C++Builder
    Réponses: 8
    Dernier message: 16/05/2006, 17h13

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