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 :

Grouper des valeurs d'une ArrayList


Sujet :

Collection et Stream Java

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 62
    Points : 18
    Points
    18
    Par défaut Grouper des valeurs d'une ArrayList
    Bonjour tout le monde,

    Je viens vous demander votre aide. Pour être plus compréhensible, je vais mettre un exemple.
    J'ai une classe voiture avec comme attribut, l'immatriculation de la voiture, la marque de la voiture, année, modèle.
    J'ai une ArrayList<Voiture> qui ait au préalable rempli. Dans mon écran, j'ai un arbre qui se présente comme suit :

    Renault, Clio :
    - 2014
    - 2015

    Renault, Mégane :
    - 2000
    - 2010

    Ford, Fiesta:
    - 1999
    - 2008

    J'aimerais grouper mon ArrayList par Marque_de_voiture,modèle, et que pour chaque Couple(Marque, Modèle), je récupère la liste des années correspondantes, comme sur mon arbre au dessus.

    Je vous remercie d'avance pour votre aide.

    Nari.

  2. #2
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 710
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur java, access, sql server
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 710
    Points : 4 791
    Points
    4 791
    Par défaut
    Pour pouvoir trier / regrouper les véhicules, il faut pouvoir dire :
    "ce véhicule A doit être classé avant ce véhicule B"
    ta classe Voiture doit donc implémenter l'interface comparable
    Dans la méthode CompareTo, tu dois donner les critères qui font qu'un objet Voiture sera classé avant un autre objet Voiture.

    Après, pour classer ton ArrayList, tu utiliseras la méthode statique Collections.sort
    voir : https://docs.oracle.com/javase/tutor...ces/order.html
    Labor improbus omnia vincit un travail acharné vient à bout de tout - Ambroise Paré (1510-1590)

    Consulter sans modération la FAQ ainsi que les bons ouvrages : http://jmdoudoux.developpez.com/cours/developpons/java/

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 62
    Points : 18
    Points
    18
    Par défaut
    Merci pour votre réponse.

    J'avais faire un truc dans le genre :

    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
     
     
                    List<Voiture> listVoitureGroup = new ArrayList<Voiture>();
    		List<String> listAnnee= new ArrayList<String>();
    		List<String> listGroupFinal = new ArrayList<String>();
     
    		for(Voiture v : listeVoiture){
    			if(!listAnnee.contains(v.getAnnee())){
    				listAnnee.add((v.getAnnee());
    				if(!listGroupFinal.contains(v.getMarque()+ " " + tire.getModele()){
    					listGroupFinal.add(v.getMarque()+ " " + tire.getModele());
    					listVoitureGroup .add(v);
    				}
    			}
    		}
    J'arrive bien à coupler par Marque,Modele (y'a surement mieux en code). Par contre, la liste des années pour chaque couple est HS. Je m'explique, je me retrouve avec 2014,2015,2000,2010,1999,2008 pour chaque couple :/
    Juste pour confirmer, le compareTo() à le même comportement que le contains() ?

  4. #4
    Membre chevronné
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Points : 1 993
    Points
    1 993
    Par défaut
    Citation Envoyé par Narizuke Voir le message
    Juste pour confirmer, le compareTo() à le même comportement que le contains() ?
    Non, l'un sert à comparer les éléments entre eux, l'autre à savoir s'ils sont égaux.
    De base, deux objets pour être égaux doivent pointer vers la même instance d'objet, mais si tu implémentes les méthodes hashCode et equals, tu peux faire en sorte que deux instance différentes d'objet soient considérées égales en fonction de leur propriétés internes


    Sinon, dans ton code, tu as une seule liste pour TOUS les groupes, donc tous les groupes auront forcement toutes les années ^^
    Il faut créer une liste par groupe
    Je ne suis pas mort, j'ai du travail !

  5. #5
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 710
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur java, access, sql server
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 710
    Points : 4 791
    Points
    4 791
    Par défaut
    compareTo te permet de définir ta propre règle de classement.

    On compare toujours un objet avec un autre objet
    Pour toi, ce sera de comparer un objet Voiture A avec un autre objet Voiture B

    Pour classer les Voitures par marque et par année tu vas créer ta propre méthode compareTo
    qui indiquera si A.getBrand() est avant B.getBrand() et A.getYear() est avant B.getYear()

    Ta classe doit implémenter l'interface comparable
    Labor improbus omnia vincit un travail acharné vient à bout de tout - Ambroise Paré (1510-1590)

    Consulter sans modération la FAQ ainsi que les bons ouvrages : http://jmdoudoux.developpez.com/cours/developpons/java/

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 62
    Points : 18
    Points
    18
    Par défaut
    Merci pour vos réponses, je vais essayer avec un compareTo()

  7. #7
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Regarde les streams et les fonctions de groupement. Pas besoin d'implémenter Comparable.

    Si tu as une classe Voiture, avec une méthode getMarque() et une méthode getAnnee() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    List<Voiture> voitures = ...;
     
    Map<Marque, List<Voiture>> groupeeParMarque = voitures.stream()
                                                           .collect(Collectors.groupingBy(Voiture::getMarque));
     
    Map<Integer, List<Voiture>> groupeeParAnnee = voitures.stream()
                                                          .collect(Collectors.groupingBy(Voiture::getAnnee));
     
    Map<Marque, Map<Integer, List<Voiture>>> groupeeParMarqueEtAnnee = voitures.stream()
                                                                               .collect(Collectors.groupingBy(Voiture::getMarque,
    							                            Collectors.groupingBy(Voiture::getAnnee)));
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 62
    Points : 18
    Points
    18
    Par défaut
    Quand je fais ma liste, il ne me propose pas le .stream(), je suppose que ça fonctionne qu'avec les dernières versions de java ?

  9. #9
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Narizuke Voir le message
    Quand je fais ma liste, il ne me propose pas le .stream(), je suppose que ça fonctionne qu'avec les dernières versions de java ?
    Java 8, oui. El il est temps d'y passer (Java 7 n'est plus supporté depuis avril — ne parlons même pas des versions antérieures).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 62
    Points : 18
    Points
    18
    Par défaut
    Malheureusement, j'ai pas le choix que de pas y passer sur la version 8. ça m'arrangerait bien sinon ^^

    Du coup, je suppose que je n'ai pas le choix que de passer par un compareTo() ?
    Si j'ai des données dans ma liste du genre :

    123XL11,Renault,Clio,2014
    352SK22,Renault,Clio,2015
    ....

    Dans mon arbre, je ne prends pas en compte mon immatriculation, mais si je fais un compareTo(), ça va me mettre grouper par immatriculation, et non par Marque,Modèle,Année ?

  11. #11
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Narizuke Voir le message
    Du coup, je suppose que je n'ai pas le choix que de passer par un compareTo() ?
    Pour le groupement, je ne vois pas trop pourquoi : des maps, des listes, et containsKey() suffisent, et bien implémenter hashcode() et equals() dans les classes spécifiques que tu utilises pour les attributs (comme la marque par exemple)

    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
    19
    List<Voiture> voitures = ...
    Map<Marque, Map<Integer, List<Voiture>>> mapParMarque = new HashMap<>();
    for(Voiture voiture : voitures) {
     
         Map<Integer, List<Voiture>>> mapParAnnee = mapParMarque.get( voiture.getMarque() ); 
         if ( mapParAnnee == null ) {
            mapParAnnee = new HashMap<>();
            mapParMarque.put( voiture.getMarque(), mapParAnnee);
         }
     
        List<Voiture> voitureParAnneeParMarque = mapParAnnee.get( voiture.getAnnee() );
        if ( voitureParAnneeParMarque  == null ) {
           voitureParAnneeParMarque  = new ArrayList<>();
           mapParAnnee.put( voiture.getAnnee(), voitureParAnneeParMarque );
        }
     
        voitureParAnneeParMarque.add(voiture);
     
    }
    Ensuite, si tu as besoin de trier l'une des Map, tu devras soit implémenter Comparable, soit implémenter un Comparator, et utiliser des TreeMap au lieu de HashMap.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 62
    Points : 18
    Points
    18
    Par défaut
    En utilisant des maps et des listes, j'ai pu me dépatouiller pour obtenir ce que je voulais.
    Je vous remercie tous pour votre aide

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

Discussions similaires

  1. Grouper des valeurs dans une nouvelle variable
    Par ruru9 dans le forum Webi
    Réponses: 3
    Dernier message: 15/11/2013, 22h55
  2. Réponses: 2
    Dernier message: 05/01/2012, 16h37
  3. Des problèmes pour ajouter valeur dans une ArrayList
    Par Fused dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 07/11/2008, 16h28
  4. [VB.NET]Récuperer des valeurs d'une autre page
    Par Dnx dans le forum ASP.NET
    Réponses: 8
    Dernier message: 12/05/2005, 16h19
  5. fonction récupérant des valeurs dans une fonction popup...
    Par petitsims dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 20/01/2005, 14h51

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