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

Langage Java Discussion :

Java 8 trier un ListOrderedMap


Sujet :

Langage Java

  1. #1
    Membre du Club
    Inscrit en
    Décembre 2006
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 84
    Points : 49
    Points
    49
    Par défaut Java 8 trier un ListOrderedMap
    Bonjour à tous,

    Je souhaite trier un ListOrderMap en fonction de ses values.

    j'ai écrit le lambda suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    list =  list.entrySet().stream().sorted(Entry.comparingByValue())
    	     .collect(Collectors.toMap(list::get,list::getValue,
                                                   (e1, e2) -> e1, ListOrderedMap::new));
    et je me retrouve avec l'erreur suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    java.lang.ClassCastException: org.apache.commons.collections.map.ListOrderedMap$ListOrderedMapEntry cannot be cast to java.lang.Integer
    Avant d'utiliser un listOrderedMap, j'avais une LinkedHashMap et je faisais ceci qui fonctionné très bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    alist = alist.entrySet().stream()
                   .sorted(Entry.comparingByValue())
                   .collect(Collectors.toMap(Entry::getKey, Entry::getValue, 
                                                      (e1, e2) -> e1,
                                                      LinkedHashMap<Long, JOB>::new));
    J'ai constater que le problème venait de l'exécution du .collect(). Je ne sais pas vraiment ce qui ne fonctionne pas. Je sais que dans le cas de la ListOrderedMap la fonction entrySet retourne un Set et non un Set<Map.Entry<K,V>> comme pour la LinkedHashMap. Du coup j'ai utilisé list::get et list::getValue au lieu de Entry::getKey et Entry::getValue. Je suppose que le soucis vient de là. Mais je ne sais pas comment faire autrement.
    Ma ListOrderedMap contient un Long comme clé et un enum comme value.

    votre expertise est la bienvenu.

    Ogtraba

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par Ogtraba Voir le message
    Je sais que dans le cas de la ListOrderedMap la fonction entrySet retourne un Set et non un Set<Map.Entry<K,V>> comme pour la LinkedHashMap. Du coup j'ai utilisé list::get et list::getValue au lieu de Entry::getKey et Entry::getValue. Je suppose que le soucis vient de là.
    Ce n'est pas parce que ce n'est pas typé dans la signature (commons collection date d'avant les generic) que ce n'est pas le cas aussi. Ce qui s'applique à une Map s'applique aussi de manière identique aux autres Map puisqu'on utilise des méthodes faisant partie de l'interface. Donc je ne vois pas pourquoi tu essaie de tapper des lambdas diffénrentes dans le cas de ListOrderedMap, si ça marche avec une LinkedHashMap, ca devrais marcher aussi avec une ListOrderedMap

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    alist = alist.entrySet().stream()
                   .sorted(Entry.comparingByValue())
                   .collect(Collectors.toMap(Entry::getKey, Entry::getValue, 
                                                      (e1, e2) -> e1,
                                                     ListOrderedMap::new));
    Pour info, ton message d'erreur viens du list::get. Comme cette méthode accepte un paramètre, elle est acceptée comme lambda. A l'exécution, on, l'appel avec l'élément courant, donc on fait un list.get(Map.Entry), ce qui évidement ne plait pas à la méthode de base qui était list.get(Integer)

  3. #3
    Membre du Club
    Inscrit en
    Décembre 2006
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 84
    Points : 49
    Points
    49
    Par défaut
    Le problème c'est que si j'utilise comme tu le suggères Entry::getKey et Entry::getValue, ça ne compile pas. j'ai l'erreur suivante.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    The type Map.Entry does not define getKey(Object) that is applicable here
    C'est pour cela que j'avais changé pour list::get

  4. #4
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par Ogtraba Voir le message
    C'est pour cela que j'avais changé pour list::get
    Sauf que cela ne veut rien dire du tout : tu est censé fournir une méthode te retournant la clef (Long) de l'objet Entry courant... donc Entry::getKey est bien la bonne méthode.
    Toi tu fourni une méthode qui attend un Long et qui retourne un JOB, ce qui est incorrect : les types ne correspondent pas !!!


    Du coup je me demande : ta ListOrderedMap est bien paramétrée ?
    Car sinon tu aurais dû avoir des erreurs de compilation...

    Ne cherches même pas à utiliser les Streams et les lambdas sans paramétrage Generics, car tu passes à coté de tout les contrôles du compilateur !


    a++

  5. #5
    Membre du Club
    Inscrit en
    Décembre 2006
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 84
    Points : 49
    Points
    49
    Par défaut
    Sauf erreur de ma part une ListOrderedMap ne se "paramétrise" pas. Du coup si je comprends bien, pas de lambda possible avec se type de map. Il faut que je fasse un tri à l'ancienne en implémentant moi même un comparable.

    Pour info après test list::get retourne la clé donc un Long et list::getValue mon enum JOB.

  6. #6
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Ogtraba Voir le message
    Sauf erreur de ma part une ListOrderedMap ne se "paramétrise" pas. Du coup si je comprends bien, pas de lambda possible avec se type de map. Il faut que je fasse un tri à l'ancienne en implémentant moi même un comparable.
    On parle bien de ListOrderedMap des Jakarta Commons Collections ? Dans ce cas les Generics ont été introduit dans la version 4.0...


    Ce n'est pas que c'est impossible d'utiliser les Streams et les lambdas, c'est juste qu'il n'y a aucune vérification des types et que tu encours donc toutes sortes de bugs difficiles à résoudre (comme dans ton cas).


    Citation Envoyé par Ogtraba Voir le message
    Pour info après test list::get retourne la clé donc un Long et list::getValue mon enum JOB.
    Le type de retour est bon... mais pas les paramètres !
    De plus cela ne fait pas ce qu'on veut.

    Tu devrais avoir (Entry)->Long pour la clef et (Entry)->JOB, or avec list::get et list::getValue tu proposes (int)->Object et (int)->Object.
    Tu n'obtiens pas d'erreur à la compilation car tout est Object... mais cela ne passe pas à l'exécution...



    a++

  7. #7
    Membre du Club
    Inscrit en
    Décembre 2006
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 84
    Points : 49
    Points
    49
    Par défaut
    Merci pour les informations. Je vais donc partir sur un tri "à l'ancienne ".

    Citation Envoyé par adiGuba Voir le message
    On parle bien de ListOrderedMap des Jakarta Commons Collections ? Dans ce cas les Generics ont été introduit dans la version 4.0...
    Je ne sais pas si nous parlons des mêmes ListOrderedMap j'importe ceci.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    org.apache.commons.collections.map.ListOrderedMap

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 21/01/2012, 14h08
  2. Trier une java.awt.List ?
    Par zarohn dans le forum Débuter
    Réponses: 1
    Dernier message: 28/09/2010, 19h02
  3. trier entiers en Java
    Par joridder dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 16/11/2008, 22h26
  4. trier une liste en java
    Par snetechen dans le forum Général Java
    Réponses: 5
    Dernier message: 10/11/2008, 12h03
  5. Trier un tableau en JAVA
    Par twingo321 dans le forum Collection et Stream
    Réponses: 5
    Dernier message: 04/10/2007, 08h45

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