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 :

Mauvais cast de Set


Sujet :

Collection et Stream Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Août 2005
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 49
    Par défaut Mauvais cast de Set
    Salut !

    J'ai encore un petit problème en Java avec les collections.
    J'ai eu un petit projet à faire (gestion de forum) dans lequel j'ai dû, à un moment, classer les users par ordre décroissant de nombre de messages postés.
    Plutôt que d'utiliser les Comparator (flemme), j'ai utilisé une TreeMap (en me débrouillant avec la clé histoire que ça classe bien par ordre décroissant), puis avec un .values(), j'ai récupéré un Set des users.

    Seulement, l'intitulé de la fonction était du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public List<User> rankUsers (){ ... }
    Donc à la fin, j'ai casté (comme un sale ) comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (List<User>) nomDeMaMap.values();
    Eclipse m'a bien indiqué qu'il n'y avait aucune erreur.
    Seulement, le professeur nous a passé des fichiers de test (JUnit, je comprends pas trop) qui me renvoient une erreur d'un type que je ne comprends pas :

    There were 1 errors:/ 13
    1) testStatUtenti(it.polito.po.test.TestR4_Stats)java.lang.ClassCastException: java.util.TreeMap$2
    at forum.Forum.rankUsers(Forum.java:90)
    at it.polito.po.test.TestR4_Stats.testStatUtenti(TestR4_Stats.java:40)
    at org.polito.softeng.util.SmartTestRunner$TestRunThread.run(SmartTestRunner.java:344)
    Alors, déjà je ne comprends pas vraiment l'Exception, j'ai une erreur de cast, oui et ? Je me doute bien que mon cast de porc n'est pas des plus esthétiques, mais j'avais pas d'autre idée sur le moment.

    L'erreur dans Forum.java se situe à la ligne du cast.
    Pour l'erreur dans TestR4_Stats.java, c'est cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Collection<User> users = f.rankUsers();
    Pourtant, je croyais que Collection<User> incluait le type List<User>, ainsi que Map<User>, etc...

    Bref, j'ai très sûrement tort, mais en revoyant mes cours, je ne comprends pas trop. Donc, si quelqu'un pouvait m'éclairer là-dessus, ce serait super sympa.

    (sinon oui, je pourrais utiliser les comparateurs, mais j'aimerais comprendre cette erreur pour éviter de la refaire la prochaine fois)

  2. #2
    Membre chevronné Avatar de spekal
    Inscrit en
    Mai 2005
    Messages
    502
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 502
    Par défaut
    Quand on apprend, faire n'importe quoi et voir ce qui se passe n'est pas une si mauvaise approche... le problème est qu'il est quelque fois vraiment difficile de comprendre !

    Je ne vois pas très bien à priori ce qui s'est passé au vu de ce que tu nous montres. Quelques commentaires :

    - Eclipse ne donne pas d'erreur sur le cast, car un cast est presque toujours possible, donc légal. Le compilateur ne délivre une erreur que lorsque on est sûr que c'est une erreur ; caster un String en Integer, par exemple, est forcément une erreur. Lors d'un cast, c'est au développeur de s'assurer que le cast est légal. Si toi même tu ne sais pas t'en assurer, c'est que, forcément, tu as fait une erreur ; que tu ne saches pas d'où aggrave ton cas, si je puis me permettre : ne fait des casts que si tu es sûr.

    - En général, l'usage simultané de génériques et de casts est l'indice presque sûr qu'il y a une connerie de conception quelque part. Ce n'est pas toujours vrai, mais c'est vraiment un indice majeur. A tout le moins un commentaire explicatif style "je sais pas faire autrement et j'ai pas le temps d'y réfléchir, excusez-moi" est le bienvenu.

    - Pour tes erreurs de List<User>, Collection<User> etc, j'ai l'impression que tu confonds des erreurs de compilation, d'exécution, etc. jUnit te délivre des erreurs d'exécution. Il te donne le stacktrace de l'exécution, et les lignes indiquées ne sont pas forcément en erreur. Par contre, en compilation, la ligne indiquée est presque toujours celle qui contient l'erreur.

    Voilà... c'est bien de faire n'importe quoi, pour essayer d'aller plus vite et pour expérimenter, mais, des fois, on se heurte à des impasses C'est ça, aussi, la vie d'un programmeur Bienvenue au club. Il te reste 1.000 vies.

  3. #3
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    L'origine de ton problème est, je pense, que tu n'as pas paramétré ta Map : Map<TypeDeCle,User>...

  4. #4
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par LorDjidane
    Pourtant, je croyais que Collection<User> incluait le type List<User>, ainsi que Map<User>, etc...
    Une Collection peut être une List ou un Set, mais ce n'est pas forcément le cas. Revois tes notions d'héritage !!!

    Une List est une Collection, mais toutes les Collections ne sont pas forcément des Lists... de la même manière qu'une Ferrati Testarossa est une voiture, mais toutes les voitures ne sont pas forcément des Ferrati Testarossa (malheureusement )



    Eclipse ne te génère pas d'erreur sur le cast car il ne connait pas le type exact de la collection lorsqu'il compile ton code. Il sait juste qu'il s'agit d'une Collection, et qu'une Collection peut être une List...

    Par contre à l'exécution le type réel de la collection est vérifié, et comme ce n'est pas une List tu obtiens un ClassCastException.


    Les cast ne sont pas des opérations sures et peuvent donc générer des ClassCastException à l'exécution (comme dans ton cas) si le type est incorect.



    Bref dans ton cas puisque tu veux utiliser une List, tu dois en créer une (puisque tu n'en as pas) et y ajouter tous tes éléments, ce qui se fait assez facilement :
    [code]return new ArrayList<User>( nomDeMaMap.values() );

    Citation Envoyé par LorDjidane
    (sinon oui, je pourrais utiliser les comparateurs, mais j'aimerais comprendre cette erreur pour éviter de la refaire la prochaine fois)
    En effet : pour trier une List, un Comparator et l'utilisation de la méthode Collections.sort() serait nettement plus approprié...


    a++

  5. #5
    Membre confirmé
    Inscrit en
    Août 2005
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 49
    Par défaut
    Bon, ben merci pour vos indications.

    C'est pas très gentil de m'incendier comme ça, il se trouve que je n'ai pas l'habitude d'apprécier coder "au hasard", et me conseiller de revoir mes cours, c'est cool mais je suis à l'étranger, j'ai jamais fait de Java avant, et les méthodes d'enseignement ici sont... différentes disons. Donc voilà.

    L'histoire du gain de temps, c'est parce que j'étais en partiel sur machine.

    Enfin, je pense que je vais me tourner vers les comparateurs, histoire d'avoir une méthode propre et plus couramment usitée.

    Merci merci, ciao.

    ---

    PS : voilà, je viens de régler ça tout connement, sans utiliser de comparateur, simplement en créant une liste (chose que j'avais bêtement oublié de faire) et en y ajoutant les éléments un par un.

    Encore une fois, merci à vous.

    (je passe en résolu)

  6. #6
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par LorDjidane
    C'est pas très gentil de m'incendier comme ça, il se trouve que je n'ai pas l'habitude d'apprécier coder "au hasard", et me conseiller de revoir mes cours, c'est cool mais je suis à l'étranger, j'ai jamais fait de Java avant, et les méthodes d'enseignement ici sont... différentes disons. Donc voilà.
    Heu... il y a une petite incompréhension...

    Que ce soit bien clair : je n'ai pas voulu incendier qui que ce soit.
    Il s'agit là des bases des langages objets. Il n'y a pas de mal à débuter mais je ne suis pas forcément au courant de ton niveau (sans compter qu'il n'y avait pas de tag [Débutant] )

    Enfin, puisque tu as une connexion internet, saches que tu as accès à un grand nombre de cours et tutoriels !

    Citation Envoyé par LorDjidane
    PS : voilà, je viens de régler ça tout connement, sans utiliser de comparateur, simplement en créant une liste (chose que j'avais bêtement oublié de faire) et en y ajoutant les éléments un par un.
    Je précise également que je t'ai donner la solution dans mon message (du coup je doute que tu l'ai lu en entier ?? bon Ok j'ai loupé ma balise [code] mais c'est quand même assez clair non :
    Citation Envoyé par adiGuba
    Bref dans ton cas puisque tu veux utiliser une List, tu dois en créer une (puisque tu n'en as pas) et y ajouter tous tes éléments, ce qui se fait assez facilement :
    [code]return new ArrayList<User>( nomDeMaMap.values() );

    Mais peut-être t'attendais-tu seulement a avoir un bout de code qui marche sans aucune explication ni détail...
    Dans ce cas il me semble que ton seul objectif était de finir ton partiel dans les temps plutôt que de comprendre ton problème et d'y trouver une solution propre...


    Enfin pour finir : oui le Comparator aurait vraiment été la méthode la plus propre...

    a++

  7. #7
    Membre confirmé
    Inscrit en
    Août 2005
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 49
    Par défaut
    Je m'excuse, je me suis un (tout petit) peu emballé.

    Avoir un bout de code tout prêt, ça ne m'intéressait pas, j'ai tellement l'habitude d'ignorer ceux qui demandent direct du code que bon, jamais je me le permettrais. Quant à mon niveau, je ne sais pas trop comment l'estimer, apparemment je suis un joli débutant (ce que je comprends, on maîtrise pas Java en 32 heures)
    Quoi qu'il en soit, j'ai vu que tu m'avais donné la solution, j'ai juste oublié de le mentionner.

    Et en fait, j'ai pas du tout pris ton message pour un incendie, je parlais plutôt d'un post un peu plus haut. J'ai beaucoup apprécié toutes tes explications, ça m'a permis de (presque) tout comprendre sur les cast.

    Voilà voilà, sans rancune.

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

Discussions similaires

  1. Cast de set<A> vers set<B> quand A hérite de B
    Par Agoudard dans le forum SL & STL
    Réponses: 7
    Dernier message: 06/04/2011, 07h38
  2. Mauvais cast (datarowview au lieu de int)
    Par Mike888 dans le forum C#
    Réponses: 13
    Dernier message: 05/02/2010, 17h51
  3. Problème de type ? Mauvais cast?
    Par zuzuu dans le forum C++
    Réponses: 4
    Dernier message: 27/09/2007, 13h59
  4. set term ^
    Par tux dans le forum Débuter
    Réponses: 8
    Dernier message: 12/10/2004, 20h42
  5. character set // Nls_lang
    Par fopicht dans le forum Oracle
    Réponses: 2
    Dernier message: 23/05/2002, 12h04

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