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 :

Retirer les doublons d'un HashMap en se basant sur la valeur


Sujet :

Collection et Stream Java

  1. #1
    Membre régulier Avatar de StripMat
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2014
    Messages
    206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 206
    Points : 93
    Points
    93
    Par défaut Retirer les doublons d'un HashMap en se basant sur la valeur
    Bonjour à tous, je suis en train de m'arracher les cheveux !!

    J'ai besoins dans un développement de retirer les doublons d'un HashMap. Ce HashMap contient des noms de colonnes provenant de tableaux et récupérés en XML via un webservice. Seulement ces XML peuvent contenir plusieurs fois le même noms de colonne et j'ai donc besoins de retirer les doublons de ma liste.

    J'ai donc développé une fonction pour retirer ces doublons, algo a priori simple et sans difficultés particulière mais pour une raison qui m'échappe, celui-ci ne fonctionne pas toujours !

    Code Java : 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
     
    static HashMap<String, HashMap<String, String>> removeDoubleColonnes(HashMap<String, HashMap<String, String>> lesColonnes)
    	{
     
    			Boolean noDouble = false;
    			Boolean Ok = false;
    			HashMap<String, HashMap<String, String>> resultat = lesColonnes;
    			System.out.println("\navant:"+lesColonnes);
    		try{	
    			while(!noDouble)
    			{
    				Iterator it = ((HashMap<String, String>)resultat.entrySet().iterator().next().getValue()).entrySet().iterator();
    				ArrayList<String> nomsColonnes = new ArrayList<String>();
    				Ok = true;
    				while(it.hasNext())
    				{
    					Map.Entry col = (Map.Entry)it.next();
    					String nomCol = col.getValue().toString().trim();
    					nomCol = nomCol.trim();
    					String idCol = col.getKey().toString();
    					if(nomsColonnes.contains(nomCol.trim()))
    					{
    						//((HashMap<String, String>)lesColonnes.entrySet().iterator().next().getValue()).remove(idCol);
    						it.remove();
    						Ok = false;
    					}
    					else
    					{
    						String tmp = new String(col.getValue().toString().trim());
    						tmp = tmp.trim();
    						nomsColonnes.add(tmp);
    					}
     
    				}
    				if(Ok)
    					noDouble = true;
     
    			}
    		}catch(Exception z){System.out.println(z.getMessage());}
    		System.out.println("\naprès :"+resultat);
    		return resultat;
    	}

    Résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    avant: {1={11=Rôle contact, 12=Rôle contact, 1=Code contrat cadre, 2=Code contrat, 3=EDS, 4=Numéro d'appel, 5=Est résilié, 6=Nom Contact, 7=Nom Contact, 8=Prenom Contact, 9=Téléphone contact, 10=Email contact}, 2={22=Code postal, 23=Ville, 24=Pays, 25=Pays, 10=Email contact, 11=Téléphone contact, 12=Libellé rôle contact site factur, 13=Adresse contact site facturation, 14=Adresse contact site facturation, 15=Code postal site facturation, 16=Ville contact site facturation, 17=RS / Adresse 1, 18=RS / Adresse 1, 19=RS Adresse postale, 1=Code contrat cadre, 2=Code contrat, 3=Code site facturation, 4=Libellé site facturation, 5=Libellé site facturation, 6=Cycle facturation, 7=Nom contact site facturation, 8=Prénom contact site facturation, 9=Email contact, 20=Adresse 2, 21=Adresse 3}, 3={1=Code contrat cadre, 2=Code contrat, 3=Code contact, 4=Nom contact signataire contrat, 5=Nom contact signataire contrat, 6=Prénom contact signataire contrat, 7=Téléphone contact, 8=Email contact}}
     
    après :{1={11=Rôle contact, 1=Code contrat cadre, 2=Code contrat, 3=EDS, 4=Numéro d'appel, 5=Est résilié, 6=Nom Contact, 8=Prenom Contact, 9=Téléphone contact, 10=Email contact}, 2={22=Code postal, 23=Ville, 24=Pays, 25=Pays, 10=Email contact, 11=Téléphone contact, 12=Libellé rôle contact site factur, 13=Adresse contact site facturation, 14=Adresse contact site facturation, 15=Code postal site facturation, 16=Ville contact site facturation, 17=RS / Adresse 1, 18=RS / Adresse 1, 19=RS Adresse postale, 1=Code contrat cadre, 2=Code contrat, 3=Code site facturation, 4=Libellé site facturation, 5=Libellé site facturation, 6=Cycle facturation, 7=Nom contact site facturation, 8=Prénom contact site facturation, 9=Email contact, 20=Adresse 2, 21=Adresse 3}, 3={1=Code contrat cadre, 2=Code contrat, 3=Code contact, 4=Nom contact signataire contrat, 5=Nom contact signataire contrat, 6=Prénom contact signataire contrat, 7=Téléphone contact, 8=Email contact}}
    Dès fois sa fonctionne "Rôle contact" (11/12) par exemple, mais pas pour "Pays" (24/25)...

    Le principe est pourtant simple...
    - Parcours de lu HashMap, le nom de la colonne existe-il dans ma liste temporaire (nomsColonnes) ? Si OUI, je supprime l'objet courant du HashMap (Iterator.remove), si NON je l'ajoute a ma liste temporaire et passe au suivant.

    Si dans ma liste j'ai trois fois le même nom, la première fois je l'ajoute a ma liste temporaire et les deux autres fois je supprime les occurrences dans mon HashMap...

    Je suis encore débutant en Java, y a peut-être plus simple et plus efficace.

  2. #2
    Modérateur

    Avatar de Robin56
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juin 2009
    Messages
    5 297
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 5 297
    Points : 13 670
    Points
    13 670
    Par défaut
    Pourquoi ne pas utiliser un HashSet pour ce genre de besoin ? (http://fmora.developpez.com/tutoriel...troduction/#L- )
    C'est plus simple et efficace.
    Responsable Java de Developpez.com (Twitter et Facebook)
    Besoin d'un article/tutoriel/cours sur Java, consulter la page cours
    N'hésitez pas à consulter la FAQ Java et à poser vos questions sur les forums d'entraide Java
    --------
    Architecte Solution
    LinkedIn : https://www.linkedin.com/in/nicolascaudard/

  3. #3
    Membre régulier Avatar de StripMat
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2014
    Messages
    206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 206
    Points : 93
    Points
    93
    Par défaut
    Je ne connaissais pas cet objet, il parait tout indiqué. Je vais regarder la doc et mettre ça en place.

    C'est néanmoins curieux que ma fonction ne retire pas tous les doublons, comme si le .equals ne fonctionnait pas ?


    EDIT: Je vais sûrement m'en sortir avec un HashSet mais j'aurais préféré garder le principe de key/value du HashMap, ou le key représente un l'index de mes colonne.

  4. #4
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Ton problème c'est que tu essaie de traiter toutes tes HashMap en même temps. (tu as une hashmap de hashmap)
    ta boucle de sortie s'arrête dès qu'une des hashmap a été traitée. D'ailleurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Iterator it = ((HashMap<String, String>)resultat.entrySet().iterator().next().getValue()).entrySet().iterator()
    Fait que tu ne pourra jamais traiter que la première hashmap interne.

    Bref tout l'algo est à revoir. A la rigueur, le equals est peut être la seule chose qui soit bonne dedans .

  5. #5
    Membre régulier Avatar de StripMat
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2014
    Messages
    206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 206
    Points : 93
    Points
    93
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Ton problème c'est que tu essaie de traiter toutes tes HashMap en même temps. (tu as une hashmap de hashmap)
    ta boucle de sortie s'arrête dès qu'une des hashmap a été traitée. D'ailleurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Iterator it = ((HashMap<String, String>)resultat.entrySet().iterator().next().getValue()).entrySet().iterator()
    Fait que tu ne pourra jamais traiter que la première hashmap interne.

    Non non, ça c'est voulu.

    Le fait d'avoir un HashMap<String, HashMap<String, String>> c'est parceque je souhaite récupérer les colonnes (Index - Nom) d'un ONGLET ! J'ai donc besoins d'associer une KEY à mon HashMap contenant les colonnes.
    Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    <document>
    <onglet>
    <colonne>col1</colonne>
    <colonne>col2</colonne>
    <colonne>col3</colonne>
    </onglet>
    <onglet>
    <colonne>col1</colonne>
    <colonne>col2</colonne>
    <colonne>col3</colonne>
    </onglet>
    </document>

    J'aurais du préciser, mais le HashMap dont je souhaite retirer les doublons est le HashMap<String, String>

  6. #6
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Ca je l'ai compris. Ce que je te dit c'est que ne traite que la première de tes N hashmap<String,String>, pas les autre, et c'est exactement l'output que tu nous a donnée, la première est traitée, mais pas la deuxième.

  7. #7
    Membre régulier Avatar de StripMat
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2014
    Messages
    206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 206
    Points : 93
    Points
    93
    Par défaut
    Pas du tout.
    Compare les deux output, certains doublons ont été retirés mais pas tous, je les ais notés en exemple en plus .

    Dans chaque HashMap<String, HashMap<String, String>> il n'y à qu'un seul HashMap<String, String>, donc ça m'est égal de ne traiter que le premier puisque je sais qu'il n'y en à qu'un. Je procède ainsi parce que plus tard j'ajoute dans un autre objet DOCUMENT chacun des onglets, représentés par ces fameux HashMap<String, HashMap<String, String>> avec un nom ou un ID comme Key et un HashMap de colonnes en value.

  8. #8
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Arrête de dire non et pars du principe que si tu n'es pas d'accord, c'est que tu ne réfléchis pas comme il faut et que tu dois recommencer du début avant de parler.

    Nous nous savons enlever des doublons. Quand on essaie, ça marche. Nous ne faisons pas d'erreur à ce sujet. Toi, si, c'est pour ça que tu es là.

    Personne ne t'a dit qu'aucun doublon n'est jamais enlevé. On t'a dit que tu n'enlèves des doublons que sur une seule HashMap, la première, et c'est bel et bien le cas. Sur les autres HashMap ils ne sont pas enlevés.

    Donc oui tu as bien des exemples de doublons enlevés et de doublons pas enlevés. C'est parce que les enlevés sont dans la HashMap que tu traites pour enlever les doublons, et les non enlevés sont dans les autres HashMap.

    Ce n'est pas compliqué : si tu as deux niveaux de conteneurs imbriqués les uns dans les autres, alors pour traiter tous les cas tu as besoin de deux boucles imbriquées pour boucler sur les deux niveaux, évidemment.
    Tu n'as qu'une seule boucle, pas d'imbrication. Forcément ça ne marchera jamais.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    Membre régulier Avatar de StripMat
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2014
    Messages
    206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 206
    Points : 93
    Points
    93
    Par défaut
    J'ai solutionné mon problème en utilisant des HashSet. C'est clairement plus adaptés quand on veut éviter les doublons mais un poil plus tricky quand on veut tout de même un système de key/value.

    Néanmoins j'ai repris mon code et je ne comprend toujours pas pourquoi certains doublons ne sont pas repérés. J'ai regardé du côté de l'encodage, ajouté des trim, testé avec des toUpper, ...

    J'ai même rajouté un while, faisant que s'il ne passe jamais dans mon Iterator.remove() il considère qu'il n'y a plus de doublons mais rien n'y fait, certains HashMap en contiennent toujours, indépendamment des caractères spéciaux ou autres pouvant se trouver dans la String (nom de colonne)...

  10. #10
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    C'est parce que tu ne traites qu'une seule HashMap, pas les autres. Il faut les traiter toutes si tu veux qu'elles soient toutes traitées.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  11. #11
    Membre régulier Avatar de StripMat
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2014
    Messages
    206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 206
    Points : 93
    Points
    93
    Par défaut
    Merci thelvin, j'apprécie de me faire recadrer de la sorte, pris de haut qui plus est, c'est bien la première fois.

    Néanmoins je sais ce que je raconte. L'objet passé en paramètre de ma fonction est un HashMap<String, HashMap<String, String>> et je sais qu'il ne contient qu'une seul occurence, qu'un seul HashMap à traiter.

    "On t'a dit que tu n'enlèves des doublons que sur une seule HashMap, la première, et c'est bel et bien le cas. Sur les autres HashMap ils ne sont pas enlevés."
    Montre moi à quoi tu fais référence, parce que moi je ne traite et ne veux traiter qu'un seul HashMap, correspondant à la value de mon parametre, et il n'y en a qu'un seul.

    Le premier sysout me print l'objet passé en paramètre, le second sysout print ce même objet après en avoir retiré les doublons.

    Je suis pas du genre a être borné buté, y a qu'a voir mes autres posts, mais faut pas abuser.
    Lisez mon poste en entier, répondez moi si vous le voulez et montrez moi où je me plante. J'ai pas posté ça dès que je me suis rendu compte que je bloquais, j'ai été chercher avant.

    C'est vendredi soir, on va se détendre et partir en week-end hein .

  12. #12
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Mais c'est qu'il est borné

    Citation Envoyé par StripMat Voir le message
    Montre moi à quoi tu fais référence, parce que moi je ne traite et ne veux traiter qu'un seul HashMap, correspondant à la value de mon parametre, et il n'y en a qu'un seul.
    ...
    Lisez mon poste en entier, répondez moi si vous le voulez et montrez moi où je me plante.
    Là où tu te plante, c'est que depuis le début on te dit que tu ne traite dans ton code que la première hasmap interne contenue dns ta hashmap externe, et que les autres sont ignorée. Tu nous dit qu'il n'y a qu'une seule hashmap interne, mais ton output dit bien le contraire:

    Code x : 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
     {1={    // Hashmap n°1, traitée
      11=Rôle contact,
       1=Code contrat cadre,
       2=Code contrat,
       3=EDS,
       4=Numéro d'appel,
       5=Est résilié,
       6=Nom Contact,
       8=Prenom Contact,
       9=Téléphone contact,
       10=Email contact
     }, // ici on sort
     2={ // Hashmap n°2, pas traitée
      22=Code postal, 
      23=Ville, 
      24=Pays, 
      25=Pays, 
      10=Email contact, 
      11=Téléphone contact, 
      12=Libellé rôle contact site factur, 
      13=Adresse contact site facturation, 
      14=Adresse contact site facturation, 
      15=Code postal site facturation, 
      16=Ville contact site facturation, 
      17=RS / Adresse 1, 
      18=RS / Adresse 1, 
      19=RS Adresse postale,
      1=Code contrat cadre,
      2=Code contrat,
      3=Code site facturation,
      4=Libellé site facturation,
      5=Libellé site facturation,
      6=Cycle facturation,
      7=Nom contact site facturation,
      8=Prénom contact site facturation,
      9=Email contact,
      20=Adresse 2,
      21=Adresse 3
     },
     3={// Hashmap n°3, pas traitée
      1=Code contrat cadre,
      2=Code contrat,
      3=Code contact,
      4=Nom contact signataire contrat,
      5=Nom contact signataire contrat,
      6=Prénom contact signataire contrat,
      7=Téléphone contact,
      8=Email contact
     }
    }

  13. #13
    Membre régulier Avatar de StripMat
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2014
    Messages
    206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 206
    Points : 93
    Points
    93
    Par défaut
    Lundi matin j'y vois plus clair.

    En fait mon bout d'code fonctionne bien, mais après avoir passé la journée dessus j'étais pas foutu de lire correctement l'output.

    C'est avant que sa à foiré, je n'étais sensé traiter qu'un seul HashMap interne et pour une raison qui m'a échappée j'en avais 1..N, forcément seul le premier était traité, comme vous me l'avez fait remarqué. Mais comme j'pensais n'en avoir qu'un, ça n'avait pas de sens pour moi...


    Merci à tous pour votre aide, vous aviez bien la solution, encore fallait-il que je vous écoutes.

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

Discussions similaires

  1. Supprimer les doublons de deux HashMaps
    Par wilddances dans le forum Collection et Stream
    Réponses: 1
    Dernier message: 27/03/2013, 13h31
  2. [MySQL] Retirer les doublons lors de l'affichage en php
    Par kakashi05 dans le forum PHP & Base de données
    Réponses: 9
    Dernier message: 12/08/2011, 17h21
  3. [AC-97] Requête qui retire les doublons en fonctions de 3 clefs primaires.
    Par Jazz_ dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 13/10/2010, 10h26
  4. Retirer les doublons de dates
    Par Mister Nono dans le forum Collection et Stream
    Réponses: 11
    Dernier message: 22/10/2007, 11h26
  5. Retirer les doublons du résultat
    Par Mister Nono dans le forum Requêtes
    Réponses: 1
    Dernier message: 08/10/2006, 12h47

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