Partage
  • Partager sur Facebook
  • Partager sur Twitter

Parcourir une liste : comparer, sélectionner

Sujet résolu
    13 avril 2021 à 14:24:13

    Bonjour,

    j'arrive pas à m'en sortir pour écrire une fonction/méthode, je pensais utiliser stream et filter mais ça ne va pas.

    Voilà le topo :

    j'ai une liste de 33 élements.

    Disons qu'un éléments à les propriétés suivantes : id, libellé, région, référence, ....

    Donc disons qu'on a une liste qui ressemble à quelques chose comme ça :

    List<Fruit> fruitList = ({0, banane, null,REF0}, {1, pomme, null,REF1}, {2, pomme verte, france,REF1}, {3, abricot, null,REF2}, ...);

     Je voudrais pouvoir filtrer fruitList, j'aimerai avoir une fonction qui ressemble à ça :

    public List<Fruit> pourUneRégion (List<Fruit> fruitList, String france){
    
    List<Fruit> fruitDisponible = new ArrayList<Fruit>();
    
    faire ici le traitement qui filtre fruitList;
    
    fruitDisponible.add(un élément de fruitList);
    
     return fruitDisponible = ({0, banane, nulll,REF0}, {2, pomme verte, francel,REF1}, {3, abricot, nulll,REF2}, ...);
    
    }
    L'idée c'est que ça me retourne une deuxième liste avec toute la liste1 mais que là ou j'avais un doublon (dans mon cas la pomme), il me retourne que celui de mon paramètre france.

    Comme vous pouvez le voir les pommes ont des libellés différents, mais des REF identique, c'est voulu.

    -
    Edité par Pitchounvivi 13 avril 2021 à 18:06:57

    • Partager sur Facebook
    • Partager sur Twitter
      13 avril 2021 à 17:18:37

      Bonjour,

      Je ne sais pas répondre à la question, mais ...

      Merci de colorer votre code à l'aide du bouton Code

      Les forums d'Openclassrooms disposent d'une fonctionnalité permettant de colorer et mettre en forme les codes source afin de les rendre plus lisibles et faciles à manipuler par les intervenants. Pour cela, il faut utiliser le bouton Code de l'éditeur, choisir un des langages proposés et coller votre code dans la zone prévue. Si vous utilisez l'éditeur de messages en mode Markdown, il faut utiliser les balises <pre class="brush: java;">Votre code ici</pre>.

      Merci de modifier votre message d'origine en fonction.

      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        13 avril 2021 à 18:04:10

        Hum, désolée, j'ai tapé ça à la main pour donner un exemple, j'ai complétement oublié que c'était du code ...

        Je modifie la colorisation.

        • Partager sur Facebook
        • Partager sur Twitter
          13 avril 2021 à 18:29:27

          > j'ai complétement oublié que c'était du code ...

          et qu'il y a des gens qui essaient de lire.

          > comme vous pouvez le voir

          Pas vraiment

          ----

          Reprenons calmement, et surtout écrivons proprement.

          Ce je comprends

          1. On a une liste de fruits

          List<Fruit> allFruits = ....;
          

          2. On veut récupérer les fruits disponibles dans un pays

          3. Dans une liste

          List<Fruit> frenchFruits = allFruits.stream()
               .filter(f -> f.getCountry().equals("France"))
               .collect(Collectors.toList());





          -
          Edité par michelbillaud 13 avril 2021 à 18:32:01

          • Partager sur Facebook
          • Partager sur Twitter
            13 avril 2021 à 20:10:54

            Bonjour,

            En fait je sature ça fait plusieurs heures que je suis dessus et mon cerveau fonctionne plus trop.

            J'ai fait ça tout à l'heure :

            fruitList.stream().filter(f -> f.getRegion()).collect(Collectors.toList());

            Si j'ai bien compris : ça permet juste de filtrer fruitList sur la région et ça le met dans une collection c'est bien ça ?

            Alors vu mon problème d'origine j'ai essayé de compléter en faisant ça :

            public List<Fruit> getRegion(List<Fruit> fruitList, Long idFrance) {
            		List<Fruit> fruitRegion = new ArrayList<Fruit>(); // List2
            
            		// On trie fruitList en regroupant les Fruit par Ref
            		Map<Long, List<Fruit>> collect = fruitList.stream().collect(Collectors.groupingBy(Fruit::getRef));
            
            		// Pour chacune des key de la Map collect
            		for (Long id : collect.keySet()) {
            			List<Fruit> fruitId = collect.get(id); // On prend la key/id
            
            			Optional<Fruit> fruitFrance = fruitId.stream().filter(
            fruit -> fruit.getRegion().equals(idFrance)).findFirst(); // on regarde juste si on en a un
            
            			// Si c'est ok on l'ajoute à la List2
            			if (fruitFrance.isPresent()) {
            fruitRegion.add(fruitFrance.get());
            			}
            		}
            
            		// parcourir la liste et faire un filtre qui vérifie qu'il n'y a pas idRef dupliqué
            		// fruitList.stream().filter(f -> f.getRef()).collect(Collectors.toList());
            
            		return fruitRegion;
            	}

            Mais là on a pas encore fini .. mais j'aimerai savoir si c'est pas trop mal parti.

            Parce là, à priori on à récupéré le fruit de la région france, mais il faut encore mettre tous les autres fruits.

            Mais dans cette list on ne veut qu'une ref de Pomme, d'où la présence de la Ref pour chacun des fruits.

            --

            Actuellement j'ai essayé de regrouper par ref, et quand j'ai 2 fruits ayant la même ref, je veux celui qui correspond à la région donnée en paramètre de la fonction.

            Le tout mis dans la liste 2 : fruitRegion (qui contient tous les fruits, MAIS seulement la pomme ayant France en région (=> la verte dans notre cas)).



            -
            Edité par Pitchounvivi 13 avril 2021 à 20:20:22

            • Partager sur Facebook
            • Partager sur Twitter
              13 avril 2021 à 20:18:20

              > En fait je sature ça fait plusieurs heures

              C'est en grande partie de ta faute si tu satures. Si tu tapais proprement tu t'y retrouverais mieux. Les débutants n'imaginent pas à quel point on sature facilement. Le seul moyen de s'en tirer, c'est de travailler proprement, tranquillement, une chose à la fois.

              Mettre les pipelines sous forme lisible, une étape par ligne

              fruitList.stream()
                 .filter(f -> f.getRegion())
                 .collect(Collectors.toList());

              > Si j'ai bien compris : ça permet juste de filtrer fruitList sur la région et ça le met dans une collection c'est bien ça ?

              Et pourquoi tu n'essaies pas ? Pour le savoir, tu as juste à faire afficher le résultat.

              Tant que tu ne l'as pas fait, c'est pas la peine de commencer autre chose. Faut pas se disperser.

              ---

              > j'aimerai savoir si c'est pas trop mal parti.

              C'est un mélange de streams, de boucles, de tests, d'optionels utilisés de travers : ça a l'air mal parti.

              Si tu faisais l'effort de rédiger, en bon français qui tient debout, ce que tu veux obtenir comme résultat, ça serait plus facile.

              -
              Edité par michelbillaud 14 avril 2021 à 13:11:55

              • Partager sur Facebook
              • Partager sur Twitter
                14 avril 2021 à 10:28:26

                Je ne vais pas rentrer dans les détails de ma vie, mais sachez seulement qu'on me met la pression et que comme personne n'a de disponibilité pour expliquer, j'ai fini ici pour chercher de l'aide.

                Je suis en alternance et je fais du mieux que je peux avec une appli Spring ancienne génération de 15 ans, qui est loin d'être clair et simple.

                --------------------------------------

                Ce que je dois faire est plus compliqué que gérer deux listes de fruits.

                Je vais essayé de reformuler :

                J'ai une liste1 de 33 fruits. J'ai un modèle de fruits de type : id, libellé, région, référence, ...

                Dans ma liste1 j'ai donc plusieurs fruits et certains peuvent être dupliqués. Typiquement dans ma liste j'ai {0,banane,null,ref0,...}, {1,pomme rouge,null,ref1,...},{2,pomme verte,france,ref1,...},{3,abricot,null,ref2,...},...

                Je voudrais une liste2, qui contiennent tous les fruits de la liste1, mais que pour ceux qui ont la même ref (dans mon exemple, ref1), que je n'ai que celui de la région que je lui ai demandé, (dans mon exemple, france, donc je veux pomme verte MAIS pas pomme rouge).

                --------------------------------------

                J'ai fais des tests, jusqu'à récupérer les 33 éléments, ça marche.

                J'ai voulu créer ce filtre et quand j'ai voulu tester j'ai eut une grosse stack, que j'essaie de résoudre pour pouvoir tester le filtre.

                Mais comme je me posais des questions, je suis venu ici.

                -------------------------------------

                Bon j'ai réussi à virer la stack mais je ne peux pas tester la ligne

                fruitList.stream()
                   .filter(f -> f.getRegion())
                   .collect(Collectors.toList());

                Car il me dit que je ne peux pas convertir un Long en Boolean

                Et si je teste ça :

                public List<Fruit> getFruitsAffichees(List<Fruit> fruitAll, Long idRegion) {
                		List<Fruit> fruitsAffichees = new ArrayList<Fruit>(); // List2
                
                		// On trie fruitAll en regroupant les fruits par IdRegion
                		Map<Long, List<Fruit>> collect = fruitAll.stream().collect(Collectors.groupingBy(Fruit::getIdRegion));
                
                		// Pour chacune des key de la Map collect
                		for (Long id : collect.keySet()) {
                			List<Fruit> fruitId = collect.get(id); // On prend la key/id
                
                			Optional<Fruit> fruitRegion = fruitId.stream().filter(
                					f -> f.getIdRegion().equals(idRegion)).findFirst(); // on regarde juste si on en a un
                
                			// Si c'est ok on l'ajoute à la List2
                			if (fruitRegion.isPresent()) {
                				fruitsAffichees.add(fruitRegion.get());
                			}
                		}
                
                
                		return fruitsAffichees;
                	}

                J'ai un NullPointerException. => il est testé directement sur le TI qui est sensé rendre 32 (avec comme seule pomme : la pomme verte).

                J'essaye de debug, mais pour l'instant je n'ai rien parce qu'il y a un problème avec la base de TNR (et ça ce n'est pas moi c'est sur).

                -
                Edité par Pitchounvivi 14 avril 2021 à 11:54:37

                • Partager sur Facebook
                • Partager sur Twitter
                  14 avril 2021 à 13:09:07

                  > j'ai eut une grosse stack

                  > j'ai réussi à virer la stack

                  > problème avec la base de TNR

                  > il est testé directement sur le TI

                  Je suis le seul à ne pas comprendre de quoi tu parles ?

                  "Stack", tu veux peut être dire que tu as eu une exception lors de l'exécution, qui a affiché la pile des appels ? Dans ce cas

                  • quel ligne
                  • quel message ?
                  ---
                  Le problème avec
                  .filter(f -> f.getRegion())

                  c'est que filter, sur un Stream<Fruit> attend comme paramètre un Predicate<Fruit>, c'est à dire une fonction qui retourne un booléen. Or l'expression f.getRegion() retourne une région, ce qui ne correspond pas.

                  C'est pour ça que j'avais écrit

                  .filter(f -> f.getCountry().equals("France"))

                  Dans ton cas, il va falloir faire quelque chose comme

                  .filter(f -> f.getIdRegion() == idRegion)
                  si tu ne veux que des fruits de la région indiquée.

                  -
                  Edité par michelbillaud 14 avril 2021 à 13:14:31

                  • Partager sur Facebook
                  • Partager sur Twitter
                    14 avril 2021 à 14:57:33

                    Je m'excuse de ne pas être clair, mais on me met beaucoup de pression, je suis sensé avoir fini tout ce qu'on me demande vendredi.

                    Et on arrête pas de me dire que je ne suis pas assez rapide. Je ne sais pas si c'est volontaire de leur part pour voir comment je tiens la pression où si je ne vais vraiment pas assez vite.

                    --------------------------------------------------------------------

                    J'essaie de le faire en TDD, j'ai écris un TI, car je veux vérifier un rendu.

                    J'ai enfin pu faire des tests car ils ont réparé la base de TNR.

                    --------------------------------------------------------------------

                    Pour le :

                    michelbillaud a écrit:

                    ---

                    Le problème avec
                    .filter(f -> f.getRegion())

                    c'est que filter, sur un Stream<Fruit> attend comme paramètre un Predicate<Fruit>, c'est à dire une fonction qui retourne un booléen. Or l'expression f.getRegion() retourne une région, ce qui ne correspond pas.

                    C'est pour ça que j'avais écrit

                    .filter(f -> f.getCountry().equals("France"))

                    Dans ton cas, il va falloir faire quelque chose comme

                    .filter(f -> f.getIdRegion() == idRegion)
                    si tu ne veux que des fruits de la région indiquée.

                    -
                    Edité par michelbillaud il y a environ 1 heure

                    Je l'ai compris en décalé ... je l'ai adapté et j'ai fais ça :

                    public List<Fruit> getFruitsAffichees(List<Fruit> fruitsATrier, Long idRegion) {
                    		List<Fruit> fruitsAffichees = new ArrayList<Fruit>(); // List2
                    
                    		// On trie fruitsATrier en regroupant les Fruit par Ref
                    		Map<Long, List<Fruit>> collect = fruitsATrier.stream().collect(groupingBy(Fruit::getIdRef));
                    
                    		// Pour chacune des key de la Map collect
                    		for (Long id : collect.keySet()) {
                    			List<Fruit> fruitId = collect.get(id); // On prend la key/id
                    
                    			// On cherche si quand on fourni une Région on en trouve 1
                    			Optional<Fruit> fruitRegion = fruitId.stream().filter(
                    					f -> f.getIdRegion() != null && f.getIdRegion().equals(idRegion)).findFirst();
                    
                    			// Si c'est ok on l'ajoute à la List2
                    			if (fruitRegion.isPresent()) {
                    				fruitsAffichees.add(fruitRegion.get());
                    			}else{

                    // Si le fruit n'est pas dans la région, on remonte celui à null
                    
                    			Optional<Fruit> fruitGénérique = fruitId.stream().filter(f -> f.getIdRegion() == null).findFirst();
                    
                    
                    			// Si c'est ok on l'ajoute à la List2
                    			if (fruitGenerique.isPresent()) {
                    				fruitsAffichees.add(fruitGenerique.get());
                    			}
                    }
                     }

                    return fruitsAffichees; }

                    Désolé pour les balise <br> qui ne sont pas dans mon code et le fait que j'ai découpé. Je ne voulais pas encore tout retraduire en fruit.

                    LE bon coté c'est que si je donne france, j'ai bien la pomme verte qui remonte.

                    Si je lui donne n'importe qu'elle autre région, il me renvoie pomme rouge.

                    Tout du moins avec les 2 TI, que j'ai testés.

                    Et avec le else que j'ai ajouté j'ai bien toujours :

                    Ma liste de fruit avec tous les éléments mais en fonction de la région j'ai le libellé qui change.

                    Parce que je suis pas très clair :

                    si je ne donne pas de région : j'ai la liste de fruits avec tous les fruits sans région (ceux qui sont à null),

                    si je donne une région : j'ai la liste de fruits avec tous les fruits sans région MAIS une seule ref de pomme.

                    ---------------------------------------------------------------------

                    C'est déjà bien mais j'ai encore une étape à faire ...

                    Si c'est ok, je mettrai en résolu.

                    -
                    Edité par Pitchounvivi 14 avril 2021 à 16:20:31

                    • Partager sur Facebook
                    • Partager sur Twitter
                      14 avril 2021 à 18:52:15

                      Un truc dans ce genre là ?

                      import java.util.List;
                      import java.util.function.Function;
                      import java.util.stream.Collectors;
                      
                      public class Fruits {
                      
                        
                          public static void main(String[] args) {
                              var allFruits = List.of( 
                                      new Fruit(0, "banane", null, "REF0"),
                                      new Fruit(1,"pomme rouge" , null, "REF1"),
                                      new Fruit(2,"pomme verte", "france", "REF1"),
                                      new Fruit(3, "abricot", null, "REF2")
                              );
                              
                              /* Si j'ai bien compris
                              - pour une référence, il peut y avoir des fruits avec ou sans région de
                              provenance
                      
                              On donne une région.
                              on construit une liste avec, pour chaque référence
                              - le fruit de la région si il y est
                              - le fruit sans provenance sinon
                              */
                              
                              sélectionnerParRégion(allFruits, "france");
                              sélectionnerParRégion(allFruits, "ouzbekistan");
                         
                          }
                      
                          private static void sélectionnerParRégion(List<Fruit> allFruits, String région) {
                              System.out.println("* Sélection pour " + région);
                              Function<List<Fruit>, Fruit> sélectionRégion = 
                                      (List<Fruit> fruits) -> {
                                          Fruit sélection = null;
                                          for (var f : fruits) {
                                              var r = f.getRégion();
                                              if (région.equals(r) || (sélection == null) && (r == null)) {
                                                  sélection = f;
                                              }
                                          }
                                          return sélection;
                                      };
                              allFruits.stream()
                                      .collect(Collectors.groupingBy(Fruit::getRéférence))
                                      .entrySet()
                                      .stream()
                                      .map( entry -> sélectionRégion.apply(entry.getValue()))
                                      .filter(f -> f != null)
                                      .forEach(System.out :: println);    
                          }
                          
                          
                          private static class Fruit {
                              final int id;
                              final String libellé;
                              final String région;
                              final String référence;
                      
                              public Fruit(int id, String libellé, String région, String référence) {
                                  this.id = id;
                                  this.libellé = libellé;
                                  this.région = région;
                                  this.référence = référence;
                              }
                      
                              public int getId() {
                                  return id;
                              }
                      
                              public String getLibellé() {
                                  return libellé;
                              }
                      
                              public String getRégion() {
                                  return région;
                              }
                      
                              public String getRéférence() {
                                  return référence;
                              }
                      
                              @Override
                              public String toString() {
                                  return "Fruit{" + "id=" + id + ", libell\u00e9=" + libellé + ", r\u00e9gion=" + région + ", r\u00e9f\u00e9rence=" + référence + '}';
                              }
                              
                              
                          }
                          
                      }
                      


                      Exécution :

                      * Sélection pour france
                      Fruit{id=2, libellé=pomme verte, région=france, référence=REF1}
                      Fruit{id=3, libellé=abricot, région=null, référence=REF2}
                      Fruit{id=0, libellé=banane, région=null, référence=REF0}
                      * Sélection pour ouzbekistan
                      Fruit{id=1, libellé=pomme rouge, région=null, référence=REF1}
                      Fruit{id=3, libellé=abricot, région=null, référence=REF2}
                      Fruit{id=0, libellé=banane, région=null, référence=REF0}



                      -
                      Edité par michelbillaud 14 avril 2021 à 18:53:55

                      • Partager sur Facebook
                      • Partager sur Twitter
                        15 avril 2021 à 10:43:21

                        Bonjour,

                        oui, c'est exactement ça, j'arrive au même résultat, mais mon écriture est beaucoup moins bien.

                        Le seul point positif, c'est que j'avais quand même réussi à avoir le rendu demandé.

                        Il faut que je m'améliore pour écrire plus simplement/ mieux.

                        ------------------------------------------------------------------

                        J'ai un autre problème que je souhaitais gérer de la même façon. Mais là je ne sais pas trop comment expliquer clairement.

                        L'équivalent serait de dire qu'on a des fruits liés ... (ce qui ne veut rien dire, j'en ai conscience).

                        quand on a des fruits liés, on ne veut afficher qu'un seul fruit mais avec le libellé du fruit lié ...

                        En fait c'est comme si on avait toujours 2 fruits ensembles systématiquement quand on a un idLiaison

                        Exemple de modèle :

                        fruit : id, libelle, region, reference, idLiaison, libelleLiaison, ...

                        La liste d'origine ressemble à ça :

                        {0,banane, null, ref0, null, null}
                        
                        {1,pomme rouge, null, ref1, null, null}
                        
                        {2,pomme verte, france, ref1, null, null}
                        
                        {3,abricot, null, ref2, id0, abricot orangé}
                        
                        {4,abricotGR, null, refX, id0, abricot orangé}
                        
                        {5,abricot, france, ref2, id1, abricot orangé}
                        
                        {6,abricotGR, france, refX, id1, abricot orangé}
                        
                        {7,abricot, france, ref2, id2, abricot jaune}
                        
                        {8,abricotGR, france, refX, id2, abricot jaune}

                        On doit donc avoir affiché :

                        pour la france : banane, pomme verte, abricot orangé (celui ayant france), abricot jaune
                        pour autre pays : banane, pomme rouge, abricot orangé (celui à null en région)

                        Les lignes ayant des idLiaisons sont fusionnées.

                        Ce n'est pas moi qui ait fait ce modèle de données et je suis obligé de le garder.

                        Je pense faire un modèle pour afficher les données avec seulement les libellés qui nous intéressent.

                        Je fini de faire ça et je mettrai en résolu.

                        MAIS je tiens déjà à te remercier pour ta patience ... je crois que je suis tout simplement entrain de péter les plombs tout seul, chez moi avec la pression qu'on m'ajoute par dessus.

                        Alors quoiqu'il arrive merci.

                        ----------------------------------------------------------------------------

                        ----------------------------------------------------------------------------

                        Bon j'y suis presque arrivé ... mais j'arrive juste pas à faire une sorte de distinct sur le idLiaison.

                        J'ai toute cette partie qui fonctionne :

                        public List<FruitAffichees> getfruitLibellePourFiltre(List<fruit> fruitSelonRegion) {
                        		List<FruitAffichees> fruitssAffichees = new ArrayList<FruitsAffichees>(); // subList
                        
                        		// On trie en regroupant les Fruit par IdRef
                        		Map<Long, List<Fruit>> collect = fruitSelonRegion.stream().collect(groupingBy(Fruit::getIdRefd));
                        
                        		// Pour chacune des key de la Map collect
                        		for (Long id : collect.keySet()) {
                        			List<Fruit> fruitId = collect.get(id); // On prend la key/id
                        
                        			// On cherche les fruits simples = sans idLiaison
                        			Optional<Fruit> fruitSansLiaison = fruitId.stream().filter(c -> c.getIdLiaison() == null)
                        					.findFirst();
                        
                        			// Si pas de liaison on récupère les infos du fruit simple
                        			if (fruitSansLiaison.isPresent()) {
                        				FruitAffichees fruitSansLiaison = new FruitAffichees(fruitSansLiaison.get().getIdRef(),
                        						fruitSansLiaison.get().getCode(), fruitSansLiaison.get().getLibelle());
                        
                        				fruitsAffichees.add(fruitSansLiaison);
                        			}


                        J'ai déjà écris pour filtrer sur l'idLiaison, mais j'arrive pas à la dire que si cet idLiaison existe déjà dans fruitsAffichees, ben tu ne l'ajoutes pas.

                        Pour l'instant, il l'ajoute systématiquement.

                        -
                        Edité par Pitchounvivi 15 avril 2021 à 16:15:46

                        • Partager sur Facebook
                        • Partager sur Twitter
                          18 avril 2021 à 10:04:53

                          J'ai un peu retravaillé le truc de l'autre jour, pour avoir quelque chose de plus "typique" des streams, avec des combinaisons de collecteurs (je savais que ça existait, mais je maîtrise pas. C'est donc l'occasion de s'y mettre) :

                          Tout d'abord, un prédicat qui sert à ne garder que les fruits qui nous intéressent :

                          • soit de la région concernée
                          • soit sans indication de région
                             Predicate<Fruit> fruitDeLaRégionOuGénérique
                                          = fruit -> {
                                              String r = fruit.getRégion();
                                              return r == null || r.equals(région);
                                          };
                          
                          ensuite, un comparateur qui indique (pour des 2 fruits qui ne sont pas d'une autre région), notre préférence pour le second si le premier est "sans provenance" (résultat -1 si on préfère le premier)
                            Comparator<Fruit> préférenceFruitRégion
                                          = (f1, f2) -> f1.getRégion() == null ? 1 : -1;
                          
                          
                          et à partir de là, ça roule
                                  Collection<Fruit> sélection = allFruits.stream()
                                          .filter(fruitDeLaRégionOuGénérique)
                                          .collect(
                                                  Collectors.groupingBy(Fruit::getRéférence,
                                                          Collectors.collectingAndThen(
                                                                  Collectors.minBy(préférenceFruitRégion),
                                                                  Optional::get))
                                          ).values();
                          
                                  sélection.forEach(System.out::println);
                          Les fruits qui ne sont pas d'une autre région,
                          • on les ventile par référence (par groupingBy)
                          • au lieu de construire une Map<String, List<Fruit>>, on chaine avec un autre collecteur pour trouver le fruit préféré pour la référence
                          • pour chaque référence, on garde le minimum (celui qu'on préfère)
                          • comme Collectors.byMin retourne un Optional<Fruit>, on combine byMin avec un déballage du Fruit par Optional::get
                          A la fin, on obtient une map référence->fruit, on ne garde que la collection de valeurs.
                          ----
                          Désolé mais
                          > une sorte de distinct sur le idLiaison.
                          je ne comprends pas du tout de quoi il peut s'agir.
                          Ca serait bien que tu fournisses un ou plusieurs jeux de données, et les résultats attendus.  J'ai joué aux devinettes la première fois, mais bon, on gagnerait du temps. Surtout toi, parce que tu as besoin que ton truc marche :-)

                          -
                          Edité par michelbillaud 18 avril 2021 à 10:17:06

                          • Partager sur Facebook
                          • Partager sur Twitter
                            2 mai 2021 à 16:04:12

                            Bonjour,

                            j'ai eu quelques problèmes de santé qui m'ont éloigné du code quelque temps.

                            Avec un peu d'aide j'ai finalement réussi à obtenir ce que je voulais.

                            Ca s'est fait en 3 étapes finalement :

                            - j'ai partitionné la liste qui remontait de la BDD

                            - fait un maker pour les élements "simples"

                            - un maker pour les éléments "liés"

                            Je poste ici si ça peut aider qq1:

                            le partitionner

                            public class FruitFiltreSimpleDouble {
                            
                            	private final Map<Boolean, List<FruitDB>> FruitAffichees;
                            
                            	public FruitFiltreSimpleDouble(List<FruitDB> fruitDb) {
                            		fruitAffichees = fruitDb.stream().collect(partitioningBy(FruitDB::isElementLiees));
                            	}
                            
                            	public List<FruitDB> getFruitDBSimples() {
                            		return fruitAffichees.get(false);
                            	}
                            
                            	public List<FruitDB> getFruitDBDoubles() {
                            		return fruitAffichees.get(true);
                            	}
                            
                            }
                            

                            le maker le plus compliqué c'est celui qui utilise une méthode pour lier en plus (le maker le plus simple ne fait que trier sur la région et mapper l'affichage)

                            public class FruitFiltreDoubleMaker {
                            
                            	public FruitFiltreDoubleMaker() {
                            
                            	}
                            
                            	public List<FruitAffichees> makeFruitFiltreDouble(List<FruitDB> fruitDoubles, Long idRegion) {
                            		List<FruitDB> fruitALier = trierSiRegionDemande(fruitDoubles, idRegion);
                            
                            		List<FruitAffichees> fruitLieesAffichees = lierEtAfficherLesFruitsDoubles(fruitALier);
                            
                            		return fruitLieesAffichees;
                            	}
                            
                            	private List<FruitDB> trierSiRegionDemande(List<FruitDB> fruitDoubles, Long idRegion) {
                            		List<FruitDB> fruitSelectionees = newArrayList();
                            
                            		Map<Long, List<FruitDB>> collect = fruitDoubles.stream().collect(groupingBy(FruitDB::getRef));
                            
                            		for (Long id : collect.keySet()) {
                            			List<FruitDB> fruitId = collect.get(id);
                            
                            			Optional<FruitDB> fruitRegion = fruitId.stream().filter(
                            					f -> f.getRegion() != null && f.getRegion().equals(idRegion)).findFirst();
                            
                            			if (fruitRegion.isPresent()) {
                            				fruitSelectionees.add(fruitRegion.get());
                            
                            			} else {
                            				Optional<FruitDB> fruitEtab = fruitId.stream().filter(f -> f.getRegion() == null)
                            						.findFirst();
                            
                            				if (fruitEtab.isPresent()) {
                            					fruitSelectionees.add(fruitEtab.get());
                            				}
                            			}
                            		}
                            		return fruitsSelectionees;
                            	}
                            
                            	private List<FruitAffichees> lierEtAfficherLesFruitsDoubles(List<FruitDB> fruitsATraiter) {
                            		List<FruitAffichees> fruitsAffichees = newArrayList();
                            
                            		Map<Long, List<FruitDB>> collectScol = fruitATraiter.stream().collect(groupingBy(FruitDB::getIdScol));
                            
                            		for (Long idCollectScol : collectScol.keySet()) {
                            			List<FruitDB> fruitScol = collectScol.get(idCollectScol);
                            
                            			Optional<FruitDB> fruit1 = fruitScol.stream().filter(f -> f.getNumOrdLie() == 1)
                            					.findFirst();
                            
                            			Optional<FruitDB> fruit2 = fruitScol.stream().filter(f -> f.getNumOrdLie() == 2)
                            					.findFirst();
                            
                            			
                            
                            FruitAffichees fruitValeur = new FruitAffichees(fruit1.get().getIdRef(), fruit2.get()
                            					.getIdRef(), fruit1.get().getScolLibelle(), fruit1.get().getUnite());
                            
                            			fruitsAffichees.add(fruitValeur);
                            		}
                            		return fruitsAffichees;
                            	}
                            
                            }
                            

                            Bon, j'ai essayer de tout retraduire, mais l'idée général et présente et pour pouvoir lier les fruits entre eux. Il a fallu ajouter un champ dans la base et dans le modele : numOrdLie.

                            J'espère que ça aidera quelqu'un.

                            Encore merci pour le temps que tu m'as consacré.



                            • Partager sur Facebook
                            • Partager sur Twitter

                            Parcourir une liste : comparer, sélectionner

                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                            • Editeur
                            • Markdown