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

avec Java Discussion :

Comparer éléments de deux listes


Sujet :

avec Java

  1. #1
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2015
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2015
    Messages : 89
    Points : 56
    Points
    56
    Par défaut Comparer éléments de deux listes
    Bonjour,

    j'ai deux listes :
    - une contenant la liste de fichiers avec extension .ext1
    - une contenant la liste de fichiers avec extension .ext2

    Je dois comparer ces deux listes de la manière suivante :
    - si dans l'une des listes j'ai un ou plusieurs fichiers qui ne sont pas présents dans l'autre liste, je dois supprimer les fichiers non présents de la liste où il se trouve de manière à ce que le contenu de la liste 1 soit équivalent à la liste 2

    Je ne sais pas si je suis très explicite, petit exemple :
    liste1 : toto1.ext1, toto2.ext1, toto3.ext1, toto4.ext1
    liste2 : toto1.ext2, toto2.ext2

    Dans ce cas je dois supprimer toto3.ext1 et toto4.ext1 de la liste1.

    Vous procéderiez comment ?

    Merci pour vos pistes.

    Cdt,

  2. #2
    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
    Hello,

    pour chaque élément de la première liste, je vérifierais s'il doit être enlevé.

    Ensuite, je ferais pareil avec la deuxième liste.

    Pour me simplifier la vie, je me ferais une méthode withoutExtension() qui enlève l'extension d'un nom de fichier.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre chevronné

    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 974
    Points : 1 825
    Points
    1 825
    Par défaut
    avec la méthode retainAll​ de l'interface Collection

    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
     
    		List<String> liste1 = new ArrayList<>(); // contient les chaînes avec extensions ext1
    		List<String> liste2 = new ArrayList<>(); // contient les chaînes avec extensions ext2
     
    		// suppression des extensions
     
    		liste1.add("toto1");
    		liste1.add("toto2");
    		liste1.add("toto3");
    		liste1.add("toto4");
    		liste1.forEach(System.out::println);
    		System.out.println("****************************");
    		liste2.add("toto1");
    		liste2.add("toto2");
    		liste2.forEach(System.out::println);
    		System.out.println("****************************");
    		liste1.retainAll(liste2);
    		liste1.forEach(System.out::println);
    donne pour la liste1

    ajouter:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    		List<File> listeFile1 = liste1.stream().map(s->Paths.get(s+".ext1").toFile()).collect(Collectors.toList());
    pour avoir le résultat dans une liste de fichiers

  4. #4
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2015
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2015
    Messages : 89
    Points : 56
    Points
    56
    Par défaut
    Bonjour,

    merci pour vos retours. J'ai essayé avec la méthode retainAll de la manière suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    List<String> expectedFilesWithoutExtension = liste2.stream().map(FilenameUtils::removeExtension).collect(toList());
    liste1.retainAll(expectedFilesWithoutExtension); => liste1 passe à 0
    liste1.forEach(System.out::println); => n'affiche rien à l'écran
    List<File> listeFile1 = liste1.stream().map(s->Paths.get(s+".ext1").toFile()).collect(Collectors.toList());
    où est mon erreur ?

    Merci. Je continue de chercher de mon côté.

  5. #5
    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
    Euh, c'est juste que retainAll() n'est pas une solution, puisque tu veux garder les fichiers avec extension, mais que tu les compares sans extension.

    A la rigueur, ça marche si tu commences par remplacer tes listes par des listes sans extension, puis tu utilises retainAll(), puis tu remets les extensions ensuite.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2015
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2015
    Messages : 89
    Points : 56
    Points
    56
    Par défaut
    Merci pour le retour.

    je suis parti sur des boucles, je dois livrer un correctif rapidement, mais je ne suis pas satisfait car ce n'est pas très propre ni optimisé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
            // TODO : améliorer / refactorer cette portion de code pour l'optimiser.
            for (String i : liste2) {
                for (String j : liste1) {
                    if (removeExtension(i).equals(removeExtension(j))) {
                        newListe1.add(i);
                        newListe2.add(j);
                    }
                }
            }
    J'ai créé deux nouvelles listes, chacune contient exactement les mêmes couples de fichiers (avec extension différente). C'est fonctionnel, cela répondu au besoin, aucun problème mais je trouve ça bof. Et niveau temps de traitement ça m'inquiète un peu si les listes à parcourir sont conséquentes.

    Comment optimiser cette portion de code ?
    En entrée, j'ai mes deux listes d'origines.

    Merci.

  7. #7
    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
    Pour des tailles conséquentes, il faut indexer d'abord. Ça nous évite de devoir faire des boucles imbriquées, et ça permet une complexité de O(n) + O(n), au lieu de O(n^2).

    - d'abord choisir la plus petite liste.
    - mettre tous ses éléments, dont tu as enlevé l'extension, dans un HashSet.
    - parcourir l'autre liste:
    -- si un élément, sans son extension, est dans le HashSet, alors il faut le garder.
    -- ajouter cet élément, sans extension, dans une liste des fichiers à garder.

    A la fin, utiliser cette unique liste résultante, des fichiers à garder. Lorsqu'on voudra des noms de fichiers avec extension, se rappeler que pour la liste 1, il faut l'extension de la liste 1, et pour la liste 2, il faut l'extension de la liste 2.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  8. #8
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2015
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2015
    Messages : 89
    Points : 56
    Points
    56
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Euh, c'est juste que retainAll() n'est pas une solution, puisque tu veux garder les fichiers avec extension, mais que tu les compares sans extension.

    A la rigueur, ça marche si tu commences par remplacer tes listes par des listes sans extension, puis tu utilises retainAll(), puis tu remets les extensions ensuite.
    Effectivement, en procédant de cette manière, c'est mieux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    List<String> liste2FilesWithoutExtension = liste2.stream().map(FilenameUtils::removeExtension).collect(toList());
    List<String> liste1FilesWithoutExtension = liste1.stream().map(FilenameUtils::removeExtension).collect(toList());
    liste1FilesWithoutExtension.retainAll(liste2FilesWithoutExtension);
    liste1FilesWithoutExtension.forEach(System.out::println);
    List<File> listeFile1 = liste1FilesWithoutExtension.stream().map(s->Paths.get(s+".ext1").toFile()).collect(Collectors.toList());
    Mais avec ce code, est-ce fonctionnel si j'ai plus d'éléments dans liste2 que liste1 et inversement ?

    Merci.

    Cdt,

  9. #9
    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
    Citation Envoyé par lasnico37 Voir le message
    EMais avec ce code, est-ce fonctionnel si j'ai plus d'éléments dans liste2 que liste1 et inversement ?
    Fonctionnel, oui. retainAll() fait qu'on se retrouve avec l'intersection des deux.

    Pour ce qui est des histoires d'optimisation, par contre, ça reste un temps au carré.

    Bon, il suffirait d'utiliser toSet() au lieu de toList() pour du linéaire.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  10. #10
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2015
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2015
    Messages : 89
    Points : 56
    Points
    56
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Fonctionnel, oui. retainAll() fait qu'on se retrouve avec l'intersection des deux.

    Pour ce qui est des histoires d'optimisation, par contre, ça reste un temps au carré.

    Bon, il suffirait d'utiliser toSet() au lieu de toList() pour du linéaire.
    Merci.

    Désolé de te demander ça, mais étant pris par le temps, aurais-tu un exemple d'optimisation avec toSet stp ?

    Merci.

  11. #11
    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
    control+R

    remplacer toList() par toSet()

    (bon, en réalité c'est mieux de ne remplacer que le deuxième)
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  12. #12
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2015
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2015
    Messages : 89
    Points : 56
    Points
    56
    Par défaut
    Hello,

    merci pour tous les retours.

    J'ai pu m'en sortir.

    Bonne après-midi.

    Cdt,

Discussions similaires

  1. Réponses: 6
    Dernier message: 10/10/2019, 15h08
  2. Concatenation des éléments de deux listes
    Par bellak dans le forum Linq
    Réponses: 7
    Dernier message: 02/06/2010, 14h32
  3. Réponses: 2
    Dernier message: 11/11/2008, 00h44
  4. Réponses: 0
    Dernier message: 08/11/2008, 17h19
  5. [VB6] Passage d'éléments entre deux listes
    Par Nesejet dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 01/08/2006, 11h41

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