Partage
  • Partager sur Facebook
  • Partager sur Twitter

Classement d'objets java

aide sur algorithme de classement

Sujet résolu
    23 octobre 2010 à 14:41:37

    Bonjour, je suis le tuto de cysboy (très bien fait d'ailleurs) et j'en suis à la POO (2e partie), sur le chapitre des classes autres que la classe Main.

    J'ai voulu créer un programme qui classe des villes par leur nombre d'habitants, et je bloque sur l'algorithme de classement par ordre croissant des villes.

    J'ai essayé de créer un tableau qui permettrait de stocker des objets que j'ai appelé "Ville". Apparemment, cela ne pose pas de soucis de faire un tableau d'objets autre que les int, double et compagnie (remarque je m'en doutais un peu vu qu'on peut faire des tableaux de String...)

    Donc j'aurai besoin de votre aide pour coder l'algorithme. J'ai déjà tenter de le coder, mais une erreur est détectée en compilation en ligne 47 de la classe Main (dépassement de la taille du tableau lors d'une attribution de valeur à une variable).

    Voilà le code source en 2 classes :

    Main.java


    package premierspasenorientéobjets;
    
    import java.util.Scanner;
    
    public class Main {
    
        
        public static void main(String[] args) {
    
            Scanner scan = new Scanner(System.in);
            System.out.print("Combien de villes voulez-vous comparer ? ");
            int compVille = scan.nextInt();
            // On crée un objet ville
            Ville tabVille[] = new Ville[compVille];
            int nbVille = 0;
            scan.nextLine();
            while (nbVille != compVille)
            {
                System.out.print("\nEntrez un nom de ville : ");
                String nVille = scan.nextLine();
                System.out.print("\nEntrez un nom de pays : ");
                String nPays = scan.nextLine();
                System.out.print("\nEntrez un nombre d'habitants : ");
                int nbHab = scan.nextInt();
    
                Ville ville = new Ville(nVille,nPays,nbHab);
                tabVille[nbVille] = ville;
                nbVille++;
    
                // ON PURGE LA LIGNE
                scan.nextLine();
            }
            
    
            for (int i = 0;i<compVille;i++)
            {
                System.out.print("Ville : " + tabVille[i].getNom());
                System.out.print("\nPays : " + tabVille[i].getPays());
                System.out.print("\nNombre d'habitants : " + tabVille[i].getHab());
                System.out.print("\n\n");
            }
    
            int retenu, a, b;
            for (int i = 0;i<compVille;i++){
                for (int j = 0;j<compVille;j++){
                    a = tabVille[j].getHab();
                    b = tabVille[j+1].getHab();
                    if (tabVille[j].getHab()>tabVille[j+1].getHab())
                    {
                        retenu = a;
                        a = b;
                        b = retenu;
                    }
                }
            }
    
            System.out.print("Voici l'ordre croissant des villes : ");
            for (int i = 0; i<compVille;i++)
            {
                System.out.println(tabVille[i].getNom() + ", située en " + tabVille[i].getPays() + ", comptant " + tabVille[i].getHab() + " habitants.");
                System.out.print("Puis vient : ");
            }
    
        }
    
    }
    

    Ville.java


    package premierspasenorientéobjets;
    
    public class Ville {
        // les variables sont privées, on ne peut pas y accéder à l'extérieur de la classe Ville
        private String nomVille;
        private String nomPays;
        private int nbHabitants;
    
        // Le constructeur sans initialisation
        public Ville(){
            System.out.println("Création d'une ville sans paramètres !");
            nomVille = "Inconnu";
            nomPays = "Inconnu";
            nbHabitants = 0;
        }
    
    
        // Le constructeur initialisateur
        public Ville(String pNom, String pPays, int pNbre)
        {
            System.out.println("Création d'une ville avec des paramètres !");
            nomVille = pNom;
            nomPays = pPays;
            nbHabitants = pNbre;
        }
    
    
        // ACCESSURS
        public String getNom()
        {
            return nomVille;
        }
        public String getPays()
        {
            return nomPays;
        }
        public int getHab()
        {
            return nbHabitants;
        }
    
        // MUTATEURS
        public void setNom(String pNom)
        {
            nomVille = pNom;
        }
        public void setPays(String pPays)
        {
            nomPays = pPays;
        }
        public void setNbHab(int pNbre)
        {
            nbHabitants = pNbre;
        }
    
        // METHODES DE CLASSES
        public String comparer(Ville v){
            String str = new String();
            if (v.getHab() > this.getHab())
                str = v.getNom()+" est plus peuplée que "+this.getNom();
            else if (v.getHab() < this.getHab())
                str = this.getNom()+" est plus peuplée que "+v.getNom();
            else
                str = v.getNom()+" et "+this.getNom()+" ont le même nombre d'habitants";
            return str;
        }
    }
    


    Alors, oui je sais la dernière méthode "comparer" et le constructeur non initialisateur ne servent à rien mais c'est un autre projet plus simpliste.

    D'une manière générale, voici ma question :
    Peut-on, à partir du moment où un tableau d'objet est créé, accéder à une variable de type private (par un accesseur j'entends bien) de l'objet en question, afin d'en établir un classement par la suite.


    En fait, je voudrais faire un peu comme en C, à savoir que je voudrais faire une fonction (donc une méthode en java) de classement de structures (donc d'objets) par rapport à un paramètre intrinsèque à cette structure. Mais je n'ai pas travaillé sur des structures en C, mais avec des tableaux de variables int ou long.


    Au final, est-ce que je peux, à travers les accesseurs, accéder à une variable private d'un objet, pour classer mes villes par ordre d'habitants croissant, dans un tableau d'objets "Ville" ?

    Merci pour votre compréhension.
    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      23 octobre 2010 à 16:41:35

      Commencons par régler l'erreur du dépassement d'index.

      lors d'un algorithme de tri il faut que tu fasses attention dans tes boucles for.
      Puisque que ta comparaison utilise j avec j+1, alors tu dois modifier ta boucle for habituelle pour ceci (c'est à la ligne 45) :

      for (int j = 0;j<compVille-1;j++)
      


      De plus il n'y a nulle part de le swap d'élément ou tu fais le changement physiquement dans le tableau.

      Citation : MMACORP

      Peut-on, à partir du moment où un tableau d'objet est créé, accéder à une variable de type private (par un accesseur j'entends bien) de l'objet en question, afin d'en établir un classement par la suite.


      sans problème



      Citation : MMACORP

      Au final, est-ce que je peux, à travers les accesseurs, accéder à une variable private d'un objet, pour classer mes villes par ordre d'habitants croissant, dans un tableau d'objets "Ville" ?


      oui aussi.

      par contre en faisant cela tu réinventes la roue (carrée en plus :( ).

      Java a déjà des outils pour effectuer des tris. Il s'agit de la classe Collections (le 's' à la fin est important). Celle classe (dans le package java.util) possède un méthode statique "sort" qui prends un élément de type List(ArrayList ou autres) en paramètre.

      Le seul hic : c'est que tout les objets contenus dans ta liste doivent OBLIGATOIREMENT implémenter l'interface Comparable. L'interface Comparable va t'obliger à redéfinir la méthode compareTo dans ta classe Ville.

      La signature de la méthode compareTo est la suivante :

      public int compareTo(Object o)
      


      cette méthode doit retourner soit un nombre négatif, 0 ou un nombre positif si l'objet en paramètres est plus petit, égal ou supérieur que l'objet courant. Et c'est toi qui décide comment le tri s'effecute (sur combien et quel paramètres...bref l'équivalent de ta méthode comparer..).

      Pour l'utiliser on fait comme ceci :

      List<Ville> villeList  = new ArraLyst<Ville>();
      //on ajoute plein de villes.		
      //on tri
      Collections.sort(villeList);
      


      Si tu as d'autres interrogations n'hésites pas.
      • Partager sur Facebook
      • Partager sur Twitter
        24 octobre 2010 à 3:40:55

        Ca y est j'ai trouvé comment ça marche :

        On écrit avant la déclaration de la classe Ville :
        import java.lang.Comparable
        


        Après on déclare la classe Ville :
        class Ville implements Comparable{
        //contenu de la classe
        }
        


        Mais ce que je trouve limite c'est qu'il faille réécrire la méthode compareTo()...

        Enfin bon, voilà le code des fichiers, dites-moi ce que vous en pensez :

        Ville.java


        package premierspasenorientéobjets;
        
        import java.lang.Comparable;
        
        class Ville implements Comparable{
            // les variables sont privées, on ne peut pas y accéder à l'extérieur de la classe Ville
            private String nomVille;
            private String nomPays;
            private int nbHabitants;
        
        
            // Le constructeur initialisateur
            public Ville(String pNom, String pPays, int pNbre)
            {
                System.out.println("Création d'une ville avec des paramètres !");
                nomVille = pNom;
                nomPays = pPays;
                nbHabitants = pNbre;
            }
        
        
            // ACCESSURS
            public String getNom()
            {
                return nomVille;
            }
            public String getPays()
            {
                return nomPays;
            }
            public int getHab()
            {
                return nbHabitants;
            }
        
            // MUTATEURS
            public void setNom(String pNom)
            {
                nomVille = pNom;
            }
            public void setPays(String pPays)
            {
                nomPays = pPays;
            }
            public void setNbHab(int pNbre)
            {
                nbHabitants = pNbre;
            }
        
            public int compareTo(Object o) {
                Ville v = (Ville)o;
                if (v.getHab() == this.getHab())
                    return 0;
                else if (v.getHab() < this.getHab())
                    return 1;
                else
                    return -1;
            }
        
        }
        


        Main.java


        package premierspasenorientéobjets;
        
        import java.util.ArrayList;
        import java.util.Collections;
        import java.util.Scanner;
        
        public class Main {
        
            
            public static void main(String[] args) {
        
                Scanner scan = new Scanner(System.in);
                int taille = 0;
                
                System.out.print("Combien de villes voulez-vous comparer ? ");
                taille = scan.nextInt();
                
                // On fait une boucle pour empêcher que l'usager ne rentre qu'une seule ville =)
                while (taille < 2)
                {
                    System.out.print("Entrez au moins 2 que je puisse comparer quelque chose ! ");
                    taille = scan.nextInt();
                }
        
                // On crée l'ArrayList pour stocker les objets
                ArrayList<Ville>listeVilles = new ArrayList<Ville>();
                int nbVille = 0;
                scan.nextLine();
                while (nbVille != taille)   // tant que l'ArrayList n'est pas remplie
                {
                    System.out.print("\nEntrez un nom de ville : ");
                    String nVille = scan.nextLine();
                    System.out.print("\nEntrez le nom du pays : ");
                    String nPays = scan.nextLine();
                    System.out.print("\nEntrez son nombre d'habitants : ");
                    int nbHab = scan.nextInt();
        
                    Ville ville = new Ville(nVille,nPays,nbHab);
                    listeVilles.add(ville);
                    nbVille++;
        
                    if ((taille - nbVille) >1)
                        System.out.println("\nIl en reste " + (taille - nbVille) + " à entrer dans l'ordi : courage !\n");
                    else if ((taille - nbVille) == 1)
                        System.out.println("\nAllez, plus qu'une ville à rentrer : vous y êtes presque !!\n");
        
        
                    // ON PURGE LA LIGNE
                    scan.nextLine();
                } //while
        
                // On affiche un petit récapitulatif
                for (int i = 0;i<listeVilles.size();i++)
                {
                    System.out.print("Ville : " + listeVilles.get(i).getNom());
                    System.out.print("\nPays : " + listeVilles.get(i).getPays());
                    System.out.print("\nNombre d'habitants : " + listeVilles.get(i).getHab());
                    System.out.print("\n\n");
                }
        
                // On trie les villes selon leur population
                Collections.sort(listeVilles);
        
                System.out.println("Voici l'ordre croissant des villes : ");
                for (int i = 0; i<listeVilles.size();i++)
                {
                    System.out.println(listeVilles.get(i).getNom() + ", située en " + listeVilles.get(i).getPays() + ", comptant " + listeVilles.get(i).getHab() + " habitants.");
                    if (i < (listeVilles.size()-1))
                        System.out.print("Puis vient : ");
                }
        
                System.out.println("\n\nVoilà c'est fini ! (Appuyez sur Enter pour quitter)");
                scan.nextLine();
        
            }
        
        }
        



        Petite question : à la ligne 26 de la classe Main, concernant la déclaration :
        ArrayList<Ville>listeVilles = new ArrayList<Ville>();
        

        Le fait de mettre <Ville> n'est pas capital, si ? Au maximum, allez, ça pourrait permettre si ce n'était pas mis d'introduire dans l'ArrayList des données qui ne sont pas compatibles entre-elles, non ? Mais pour ça on peut faire une gestion d'erreurs non, je me trompe ?
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          29 octobre 2010 à 17:23:55

          Pour répondre à ta question :

          Citation : MMACORP

          Mais ce que je trouve limite c'est qu'il faille réécrire la méthode compareTo()...



          Quand tu y penses c'est logique...

          Le langage Java (ou autre sous-:) langage ne peux pas prévoir toutes les classes du monde entier, et de plus, java, ne peut pas savoir comment les classes vont se trier. Dans ce contexte, java nous fourni un interface (Comparable) qui GARANTIE que toute classes qui implémente cette interface (toujours Comparable) saura comment trier les objets entre-eux.

          Donc la méthode "Collections.Sort" que tu utilises est de type :
          Collections.Sort(T extends Comparable) 
          // en gros T veux dire n'importe quelle collection qui implémente
           //l'interface Comaprable
          




          Citation : MMACORP

          Le fait de mettre <Ville> n'est pas capital, si ? Au maximum, allez, ça pourrait permettre si ce n'était pas mis d'introduire dans l'ArrayList des données qui ne sont pas compatibles entre-elles, non ? Mais pour ça on peut faire une gestion d'erreurs non, je me trompe ?



          C'est pas capital, par défaut si tu ne mets pas de chevron le type est Objet

          mais je te conseille de toujours de typer ta Collection avec les chevrons afin d'éviter les erreurs.
          • Partager sur Facebook
          • Partager sur Twitter
            29 octobre 2010 à 19:45:17

            Bonsoir c'est juste une petite erreur dans le tri du tableau tbaVille
            int retenu, a, b;
            for (int i = 0;i<compVille;i++){
            for (int j = 0;j<compVille;j++){
            a = tabVille[j].getHab();
            b = tabVille[j+1].getHab();
            if (tabVille[j].getHab()>tabVille[j+1].getHab())
            {
            retenu = a;
            a = b;
            b = retenu;
            }
            }
            }
            dans la deuxieme boucle il faut commencer de i+1 c'est pas 0
            int retenu, a, b;
            for (int i = 0;i<compVille;i++){
            for (int j = i+1;j<compVille;j++){
            a = tabVille[i].getHab();
            b = tabVille[j].getHab();
            if (tabVille[i].getHab()>tabVille[j].getHab())
            {
            retenu = a;
            a = b;
            b = retenu;
            }
            }
            }
            • Partager sur Facebook
            • Partager sur Twitter

            Classement d'objets java

            × 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