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 :

Map + wildcard


Sujet :

Collection et Stream Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 29
    Par défaut Map + wildcard
    Bonjour, je souhaite utiliser la généricité sur les maps, à l'aide des wildcards. Seulement que dois-je retourner comme type pour le Set de la méthode entrySet ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      public void m(Map<?,?> map) {
        type     set = map.entrySet();
      }
    }
    Merci par avance.

  2. #2
    Membre très actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 138
    Par défaut
    Si tu compte utiliser les types paramétrés de la map, tu es obligé de les nommer.

    Pour cela, tu déclare au début de la fonction 2 types génériques entre "<>", et tu remplace les ? par ces types génériques.

    Cela donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public <E,F> void m(Map<E,F> map) {
    	    Set<Map.Entry<E, F>>     set = map.entrySet();
    	  }
    Pense à marquer la discution comme résolue.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 29
    Par défaut
    Mais si je souhaite conserver une map qui prend "n'importe quoi", il n'y a pas un autre moyen en conservant cette signature ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public static void f(Map<?,?> map);

  4. #4
    Membre très actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 138
    Par défaut
    Si tu veux garder les wildcards, tu peux utiliser cette syntaxe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public void m(Map<?,?> map) {
        Set<?>     set = map.entrySet();
      }
    Cela signifie que la variable set est de type Set<Object>, et que tu devras convertir les éléments du set en Map.Entry.
    La syntaxe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public void m(Map<?,?> map) {
       Set<Map.Entry<?, ?>> set = map.entrySet();
    }
    n'est pas permise, parce que Java n'a pas les moyen de savoir si le 1er "?" de la map correspond au 1er "?" de la Map.Entry.
    Donc si tu veux t'amuser avec les conversions, libre à toi.
    Cependant, les "?" correspondent toujours à un type générique avec un nom qui n'a pas été donné.
    En fait, la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public void m(Map<?,?> map)
    est strictement équivalente à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public <E,F> void m(Map<E,F> map)
    Elle sont toutes les deux "aussi" génériques. Partout où tu peux appliquer l'une tu peux appliquer l'autre.
    On utilise les "?" quant on n'a pas besoin d'utiliser le type.
    Par exemple, si ta fonction m ne fait qu'appeler size() ou isEmpty() sur la map, tu ne vas pas t'embêter à donner un nom au 1er ou au 2eme paramètre générique. Dans ce cas, tu utilise les "?".
    Si par contre, tu souhaite parcourir la map, tu n'es pas obligé d'utiliser la 2ème forme, mais c'est quand même plus simple (tu auras moins de conversion de type).
    Tu peux remplacer E et F par ce que tu veux (MaClasseGenerique si tu veux). La seule chose qu'il faut, c'est qu'il n'y ai pas de classe qui portent ce nom.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 29
    Par défaut
    Daccord, merci pour les infos.
    En bidouillant, j'ai vu que ce code-là passait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Set<? extends Map.Entry<?,?>> set = map.entrySet();
    Est-ce correct? Et si oui, que signifie-t-il exactement, et quelle est la différence par rapport à ceci que j'aurais écrit instinctivement (et qui est faux) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Set<Map.Entry<?,?>> set = map.entrySet();

  6. #6
    Membre très actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 138
    Par défaut
    Le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Set<? extends Map.Entry<?,?>> set = map.entrySet();
    fonctionner.
    La raison est que le type Set<? extends Map.Entry<?,?>> est le type Set avec un paramètre générique qui est soit Map.Entry<?,?>, soit un sous type de Map.Entry<?,?>. Comme le paramètre de la fonction map est du type Map<?,?>, la variable map peut pointer vers un objet qui est une sous classe de l'interface Map. Je n'y avait pas pensé.

    Donc, si tu ne peux pas utiliser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Set<Map.Entry<?,?>> set = map.entrySet();
    c'est aussi parce que le type Set<Map.Entry<?,?>> n'est pas compatible si la map est une sous classe de Map.
    Pour faire simple, si tu as une classe X qui est une sous classe de Y, C[X] n'est pas compatible avec C[Y]. Par contre, C[X] est compatible avec C[? extends Y].

    Donc pour ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public void m(Map<?,?> map) {
        Set<? extends Map.Entry<?,?>> set = map.entrySet();
        for(Z o:set)
        {
           System.out.println("o="+o);
        }
      }
    quel peut être le type de o ?
    Z peut être Map.Entry<?,?>.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 29
    Par défaut
    Merci pour tous ces éclaircissements.

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

Discussions similaires

  1. Bump mapping
    Par Francky033 dans le forum DirectX
    Réponses: 7
    Dernier message: 22/11/2003, 18h35
  2. [EJB2.1 Entity] [BES] Mapping automatique et clés étrangères
    Par Bobby McGee dans le forum Java EE
    Réponses: 3
    Dernier message: 15/10/2003, 10h33
  3. Réponses: 2
    Dernier message: 11/07/2003, 18h24
  4. Problème avec memory mapping
    Par gemai dans le forum C
    Réponses: 13
    Dernier message: 04/07/2003, 09h50
  5. Editeur de MAP en delphi pour jeux directX
    Par PetitScorpion dans le forum DirectX
    Réponses: 5
    Dernier message: 09/07/2002, 18h47

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