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 :

Problème de liste de génériques


Sujet :

Langage Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 84
    Points : 42
    Points
    42
    Par défaut Problème de liste de génériques
    Bonjour à Tous,

    Malgré mes recherches sur le sujet je tourne en rond. c'est surement très simple mais je galère sur la création d'une liste d'élément généric.

    je m'explique:
    je réalise un ploter pour afficher des courbes donc.

    j'ai la class
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Curve<T extends Number, M extends AbstractPoint<T,M>, C extends Curve<T,M,C>>
    puis les class files:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    CurveComplex extends Curve<Complex, PointComplex, CurveComplex>
    CurveDouble extends Curve<Double, PointDouble, CurveDouble>
    CurveSparam extends CurveComplex
    ca ok c'est bon.

    J'ai des class de list de ces objets soit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CurvesAbstract <C extends Curve<?,?,?>> extends AbstractGroup<String, C>  // rq : AbstractGroup contient la gestion d'un objet List<C>
     
    CurvesComplex extends CurvesAbstract<CurveComplex>
    CurvesDouble extends CurvesAbstract<CurveDouble>
    CurvesSparam extends CurvesComplex

    Dans ma class ploter je cherche à avoir un object pouvant lister tous les types de courbe pour les afficher soit un type generic :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CurvesAbstract<?> curves = new CurvesAbstract<Curve<?,?,?>>();
    Toutefois je ne peux pas faire cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    curves.addCurves(new CurvesSparam());
     
    //Voici le message d'erreur que j'ai:
    The method addCurves(CurvesAbstract<capture#1-of ?>) in the type CurvesAbstract<capture#1-of ?> is not applicable for the arguments (CurvesSparam)
    Je pense comprendre que le compilateur n'accepte pas que je puisse ajouter des objets même génériques mais différents au sein d'une même liste. Ok mais comment le faire tout de même ?

    quelqu'un a t-il une piste pour me sortir de là?

    J'ai pensé à faire une class intégrant la gestion de plusieurs listes de chaque type hérité de "Curve" mais cela va être très complexe de gérer et pas très optimisé. De plus si je rajoute un fils à "Curve" il faudra que je modifie cette class pour en tenir compte.

    Au final je veux simplement faire une liste de "Curve" avec les fonctions add, remove, get(int i) et iterator<Curve>.

    Merci d'avance pour votre aide.

    Sébastien.

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 565
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 565
    Points : 21 630
    Points
    21 630
    Par défaut
    Citation Envoyé par <_oodTi96Tiboo_> Voir le message
    Au final je veux simplement faire une liste de "Curve" avec les fonctions add, remove, get(int i) et iterator<Curve>.
    Que penses-tu de List<Curve<?, ?, ?>> dans ce cas ?

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 84
    Points : 42
    Points
    42
    Par défaut
    Bonsoir Thelvin,

    C'est ce que je fait indirectement :

    Dans :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CurvesAbstract<?> curves = new CurvesAbstract<Curve<?,?,?>>();
    curves est donc un CurvesAbstract<C extends Curve<?,?,?>> qui hérite de AbstractGroup<String, C> qui à son tour implémente un objet List<C> ou C étant un Curve<?,?,?>.

    Donc l'implémentation curves est un objet qui contient un attribut de type List<Curve<?,?,?>>

    c'est bien là mon soucis. c'est que sur le papier cela doit marché. Donc je pense que j'ai loupé un truc. mais quoi???

    Sébastien.

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 565
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 565
    Points : 21 630
    Points
    21 630
    Par défaut
    Citation Envoyé par <_oodTi96Tiboo_> Voir le message
    C'est ce que je fait indirectement :

    Dans :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CurvesAbstract<?> curves = new CurvesAbstract<Curve<?,?,?>>();
    Ah bon ?

    Si <?> était la même chose que <Curve<?, ?, ?>> je pense qu'on ne taperai jamais <Curve<?, ?, ?>>. On taperai juste <?>. Mais je serais bien infoutu de savoir comment, dans ce cas, le compilateur a fait pour deviner qu'un ? ça veut forcément dire Curve<?, ?, ?> et pas TroupeauDeMoutons<LaineBleue>.

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Tu dois bien faire attetion avec tes ?

    ? ne veux pas dire "n'importe quoi", il veux dire "quelque chose de bien précis, mais que je ne connais pas". Pour dire n'importe quoi, utilise Object!

    List<?> <-- ça prend quelque chose de précis que je ne connais pas, je ne peux donc pas faire de add(maString) dedans.
    List<? extends Number> <-- ça prend quelque chose de précis étendant Number que je ne connais pas, je ne peux donc pas faire de add(Integer) dedans.
    List<? super Number> <-- ça prend quelque chose de précis qui est le parent de Number que je ne connais pas, je peux donc faire de add(Integer) dedans, car ce qui est parent de Number est aussi parent de Integer. Mais un get() me retournera de l'Object, car je ne sais toujours pas de quel parent on parle.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 84
    Points : 42
    Points
    42
    Par défaut
    Bonjour Thelvin,

    La définition de la class CurvesAbstract indique que le paramètre généric de la class extends de Curve<?,?,?> (voir mon premier post). Donc le compilateur sait que dans la déclaration CurvesAbstract<?> le ? est de type Curve<?,?,?>.

    Je sais, au lieu d'écrire cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CurvesAbstract<?> curves = new CurvesAbstract<Curve<?,?,?>>();
    j'aurai du écrire ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CurvesAbstract<Curve<?,?,?>> curves = new CurvesAbstract<Curve<?,?,?>>();
    Mais je suis fainéant. On se refait pas.

    je ne pense pas que le problème vienne de là. Par soucis de prudence j'ai testé la deuxième écriture ci-dessus. j'ai le même message d'erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    The method addCurves(CurvesAbstract<Curve<?,?,?>>) in the type CurvesAbstract<Curve<?,?,?>> is not applicable for the arguments (CurvesSparam)
    or je ne comprend pas, la méthode addCurves(CurvesAbstract<Curve<?,?,?>>) de la class CurvesAbstract<Curve<?,?,?>> devrait être applicable à un CurvesSparam puisque CurvesSparam hérite bien de CurvesAbstract<Curve<?,?,?>> ou plus exactement de CurvesAbstract<CurvesComplex> où CurvesComplex hérite de Curve<Complex, PointComplex, CurveComplex>
    Pourtant le compilateur me dit le contraire.

    Sébastien.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 84
    Points : 42
    Points
    42
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Tu dois bien faire attetion avec tes ?

    ? ne veux pas dire "n'importe quoi", il veux dire "quelque chose de bien précis, mais que je ne connais pas". Pour dire n'importe quoi, utilise Object!

    List<?> <-- ça prend quelque chose de précis que je ne connais pas, je ne peux donc pas faire de add(maString) dedans.
    List<? extends Number> <-- ça prend quelque chose de précis étendant Number que je ne connais pas, je ne peux donc pas faire de add(Integer) dedans.
    List<? super Number> <-- ça prend quelque chose de précis qui est le parent de Number que je ne connais pas, je peux donc faire de add(Integer) dedans, car ce qui est parent de Number est aussi parent de Integer. Mais un get() me retournera de l'Object, car je ne sais toujours pas de quel parent on parle.
    j'ai l'impression de bien utiliser les <?>. Ils sont toujours spécifié dans la définition des class en utilisant un extends. Donc normalement il n'y a pas de confusion possible.
    je pense que mon dernier poste précise bien cela.

    Séb.

    PS : je ne connaissais pas les <? super ...> même si je vois pas encore l'intérêt (je vais chercher), c'est intéressant de savoir que cela existe.

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Visiblement tu n'as toujours pas compris car je t'expliquais là exactement ton message d'erreur:


    The method addCurves(CurvesAbstract<Curve<?,?,?>>) .... is not applicable for the arguments (CurvesSparam)

    CurvesSparam est de type Curve<Double, PointDouble, CurveDouble>

    or, ?, ?, ? signifie 'quelque chose je ne sais pas quoi' et toi tu lui passe des Double,PointDouble,CurveDouble. La réaction du compilateur est de te dire:
    Ha ben non désolé, tes "n'importe quoi, ça ne correspond pas Nécessairement à Double,PointDouble,CurveDouble, donc je ne peux pas garantir que le résultat est correct.


    Pour prendre un autre exemple,

    CurvesAbstract<Curve<?,?,?>> curves= CurvesComplex();
    curves.addCurves(new CurvesSparam()); // en tout logique, ce n'est pas bon
    curves.addCurves(new CurvesComplex()); // en tout logique, c'est bon

    mais comme le compilateur ne connais que "CurvesAbstract<Curve<?,?,?>>" pour curves, il est bien supposé prendre une décision sur cette base et c'est décision c'est "pas possible"

  9. #9
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 565
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 565
    Points : 21 630
    Points
    21 630
    Par défaut
    Citation Envoyé par <_oodTi96Tiboo_> Voir le message
    je ne pense pas que le problème vienne de là.
    C'est bien de penser des trucs. C'est juste dommage que là, ce soit faux.

    Citation Envoyé par <_oodTi96Tiboo_> Voir le message
    Par soucis de prudence j'ai testé la deuxième écriture ci-dessus. j'ai le même message d'erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    The method addCurves(CurvesAbstract<Curve<?,?,?>>) in the type CurvesAbstract<Curve<?,?,?>> is not applicable for the arguments (CurvesSparam)
    C'est clairement pas le même message.
    Il y a un s en trop dans CurvesSparam, ou alors j'ai rien compris de ce que tu essaies de faire. En tout cas, avec les types que tu as déclaré, ça ne peut marcher qu'avec CurveSparam avec juste un grand S et pas de petit s.

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 84
    Points : 42
    Points
    42
    Par défaut
    Bonjour Tchize_,

    Je comprend bien qu'il y a quelque chose que je ne comprend pas . Merci de prendre de ton temps pour m'aider.

    Tu viens de me poser une colle et mis le doigt sur mon problème de compréhension. Si l'on m'avait demandé si dans une class List<? extends Number> on pouvez faire un add(Integer) j'aurai dis oui car Integer est un Number.
    Or comme tu le dis (et je viens de le vérifier, sans vouloir t'offenser) cela ne marche pas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    List<? extends Number> list = new ArrayList<Integer>();
    list.add(Integer.valueOf(3));  --> error
     
    Msg Error:
    The method add(capture#1-of ? extends Number) in the type List<capture#1-of ? extends Number> is not applicable for the arguments (Integer)
    cela ressemble fort à mon message d'erreur.

    Si je comprends bien et cela est logique en fait ()
    - Lorsque je créer ma list (List<? extends Number> list) je dis au compilateur que c'est une liste de quelque chose qui hérite de Number.
    - à l'implémentation je suis obligé de lui dire le type réelle (ici Integer qui hérite bien de Number).
    - à l'utilisation le add(Integer) plante car le compilateur ne sait pas ce qui est traité par la liste même si il sait que c'est un type hérité de Number, il ne sais pas lequel.

    J'ai juste maintenant?

    Seule soucis c'est que j'ai toujours pas de solution pour mon implémentation de mon ploter. même si je progresse dans la compréhension du generic.
    en passant j'ai voulu me simplifier la vie en utilisant le generic pour ma lib math (afin éviter d'écrire 2 fois les class vecteur, matrix, FFT, curve.... pour les double et complex et la maintenance également) et au final cela fait 3 fois que je réécris toute ma lib (>180 class) .... bref

    Je rappelle le besoin, je souhaite avoir une class qui contient tous mes objects Curve (CurveComplex, CurveDouble, CurveSparam...). On vient de voir que l'implémentation de List<Curve<?,?,?>> ne marche pas. (pufff c'était évident ... )

    Donc quelle serait les possibilités pour faire ce conteneur d'objet Curve?

    avez vous une idée? passer par une interface?

    Séb.

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 84
    Points : 42
    Points
    42
    Par défaut
    Citation Envoyé par thelvin Voir le message
    C'est bien de penser des trucs. C'est juste dommage que là, ce soit faux.
    Je crois que c'est là un des problèmes les plus élémentaires... Le principale c'est d'être ouvert pour se corriger. Jusqu'à preuve du contraire...

    Citation Envoyé par thelvin Voir le message
    C'est clairement pas le même message.
    Il y a un s en trop dans CurvesSparam, ou alors j'ai rien compris de ce que tu essaies de faire. En tout cas, avec les types que tu as déclaré, ça ne peut marcher qu'avec CurveSparam avec juste un grand S et pas de petit s.
    oui j'ai fait n'importe quoi. je suis allé trop vite (c'est qu'en fait, j'ai également des class "avec un s à curve" (CurvesDouble, CurvesComplex, CurvesSparam...) qui implémente des listes de curve par type de donnée (double, complex...). Mais là c'est simple.)

    Séb.

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Citation Envoyé par <_oodTi96Tiboo_> Voir le message
    - à l'utilisation le add(Integer) plante car le compilateur ne sait pas ce qui est traité par la liste même si il sait que c'est un type hérité de Number, il ne sais pas lequel.

    J'ai juste maintenant?
    Voilà, donc en fait, les généric, ce n'est pas aussi simple que l'héritage


    Et donc, il faut éviter au maximum, dans ta classe, de mettre des paramètres en ?, a l'exception des paramètres définissant la classe. Par exemple:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public class MaClass<C extends Number>{
          public void addAutreListe(MaClass<? extends C> autre)
    }
     
    MaClass<Integer> maClassi = new MaClass<Integer>();
    maClassi.add(.....)  // ok
    MaClass<?> maClassx = new MaClass<Integer>();
    maClassx.add(.....)  // pas bien, en déclarant maClassx avec un ? tu perd la possibilité d'utiliser certaines méthodes.
    un bonne règle c'est:

    soit spécifique quand tu déclare tes variables, c'est toujours mieux
    soit générique quand tu déclare des paramètres, autant que possible, ça laisse plus de libertés à l'appelant
    soit aussi spécifique que possible dans tes valeur de retour de méthodes, ça laisse plus de libertés à l'appelant.

Discussions similaires

  1. [MySQL] Problème de liste déroulante dynamique
    Par vincedjs dans le forum PHP & Base de données
    Réponses: 13
    Dernier message: 03/03/2006, 16h38
  2. Problème de liste déroulante et js...
    Par Empty_body dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 03/03/2006, 10h44
  3. [MySQL] Problème de listes déroulantes liées avec requêtes sql
    Par richton95 dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 21/12/2005, 16h04
  4. Problème avec liste déroulante
    Par Invité dans le forum IHM
    Réponses: 2
    Dernier message: 14/12/2005, 21h04
  5. Problème avec listes liées entre elles et bouton "précé
    Par Oluha dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 02/08/2005, 15h10

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