Partage
  • Partager sur Facebook
  • Partager sur Twitter

Tri de collections avec plusieurs critères

    27 mai 2019 à 14:38:33

    Bonjour,

    j'ai une arraylist de produits que je veux trier selon le prix puis la référence et enfin la designation, si le prix est égal je trie par réference et si la réference est égale je trie par désignation, mais mon code n'affiche pas le résultat attendu, ma classe Produit implémente Comparable,

    voici mon code :

    <code>

      // Comparator pour le tri des produits par prix 

         public static Comparator<Produit> ComparatorPrix = new Comparator<Produit>() {

            @Override

            public int compare(Produit p1, Produit p2) {

                   if(p1.getPrix()!=(p2.getPrix())){return (int)(p1.getPrix()-(p2.getPrix()));

                   }else if((p1.getDesignation().compareTo(p2.getDesignation())!=0)) {

               return (int)(p1.getDesignation().compareTo(p2.getDesignation()));

                }else           return (int)(p1.getIdentifiant() - p2.getIdentifiant());

            }};

    <code/>

    MERCI d'avance pour votre aide

    • Partager sur Facebook
    • Partager sur Twitter
      28 mai 2019 à 11:12:01

      Bonjour,

      La documentation du compareTo dit ceci :

      Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.

      En gros, et souvent pas convention (c'est pas une obligation) on retourne -1 s'il est inférieur, 0 si égal, et 1 si supérieur. Mais comme le dit la doc, tu dois en réalité renvoyer une valeur négative si l'objet est inférieur, une valeur de 0 si égal et une valeur positive si l'objet est supérieur.

      Ici, tu fais un "return" a chaque comparaison.

      Ce qu'il faudrait faire, c'est une comparaison sur chaque critère PUIS retourner une valeur. A toi d'arranger ton code pour cela !

      Bon courage,

      Julien

      • Partager sur Facebook
      • Partager sur Twitter

      Site personnel : Julien Gidel - AutoMatePHPresentation

        29 mai 2019 à 2:54:54

        public class ComparatorProduit implements Comparator<Produit>{
        	public int compare(Produit p1, Produit p2)
        	{
        		  if(p1.getPrix() == p2.getPrix())
        		  {
        			  if(p1.getReference() == p2.getReference())
        			  {
        				  // tri par désignation
        				  return p1.getDesignation().compareTo(p2.getDesignation());
        			  }
        			  else
        			  {
        				  // tri par référence
        				  return p1.getReference() - p2.getReference();
        			  }
                  }
        		  else
        		  {
        			  // tri par prix
        			  return p1.getPrix() - p2.getPrix();
        		  }
        	}
        
        }
        		ArrayList<Produit> listeProduit = new ArrayList<>();
        		
        		ComparatorProduit comparatorProduit = new ComparatorProduit();
        		Collections.sort(listeProduit, comparatorProduit);
        


        • Partager sur Facebook
        • Partager sur Twitter

        La persévérance est ma vertu.

          29 mai 2019 à 9:14:17

          C'est beaucoup plus simple depuis Java 8 (2014).  Faut dire à vos profs de mettre leurs cours à jour.

          Comment faire ?

          ArrayList<Produit> produits = ....;
          
          produits.sort(
                 comparing(Produit::getPrix)                   // comparer par prix
                 .thenComparing(Produit::getReference)         // puis par référence
                 .thenComparing(Produit::getDesignation)       // et sinon par désignation
          );

          Explications


          1. Les collections ont désormais une méthode sort(Comparator). Vous pouvez laisser tomber la méthode statique Collection.sort

          2. La méthode statique java.util.Comparator.comparing fabrique un Comparator à partir d'une méthode  applicable aux objets à comparer

          3. Notation   Classe::methode pour désigner une méthode

          4. la méthode .thenComparing  de Comparator (*) permet d'enchainer des comparaisons

          Penser à importer

          import static java.util.Comparator.comparing;


          (*) Comparator est une interface, mais depuis Java 8 les interfaces ont des méthodes par défaut. En bonus, il y reversed() pour inverser un comparateur.

          people.sort(
                 comparing(Person::getName)                   // par ordre de nom
                 .thenComparing(Person::getAge).reversed()    // et par age décroissant
          );
          

          ----------

          Si pour des raisons X ou Y, on doit se la jouer "Java des dinosaures", il y a quand même une manière plus adroite d'enchainer les combinaisons de comparateurs

          int compare(Produit p1, Produit p2) {
             
             int r = p1.getPrix() - p2.getPrix();
             if (r == 0) {
                  r =  p1.getReference().compareTo(p2.getReference());
             }
             if (r == 0) {
                  r =  p1.getDesignation().compareTo(p2.getDesignation());
             }
             return r;
          }
          
          

          à chaque niveau  if(r == 0)  se lit "si on n'a pas encore réussi à les départager, voyons  ce que donne le critère suivant".


          -
          Edité par michelbillaud 29 mai 2019 à 9:27:33

          • Partager sur Facebook
          • Partager sur Twitter
            29 mai 2019 à 14:05:29

            Merci michel pour des informations c'est vrais que c'est plus simple avec ces connaissances.
            • Partager sur Facebook
            • Partager sur Twitter

            La persévérance est ma vertu.

              29 mai 2019 à 15:12:40

              Merci à toi Michel, j'ai trouvé cette syntaxe lorsque j'ai recherché ensuite pour ce sujet. C'est bien plus pratique.

              • Partager sur Facebook
              • Partager sur Twitter

              Site personnel : Julien Gidel - AutoMatePHPresentation

                29 mai 2019 à 16:20:09

                J'ai trouvé ça moi aussi en mettant mon cours à jour :-)
                • Partager sur Facebook
                • Partager sur Twitter

                Tri de collections avec plusieurs critères

                × 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