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 in generics


Sujet :

Collection et Stream Java

  1. #1
    Membre confirmé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 106
    Par défaut Map in generics
    Bonjour

    Je me demande pourquoi dans l'interface Map<K, V>, il y a la méthode "V get(Object key)" et non "V get(K key)"? il doit y avoir une raison précise pour cela mais je ne vois pas laquelle.

    Merci

  2. #2
    Membre Expert
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Par défaut
    plusieurs raisons ont été avancées sur différents forums. Il me semble me souvenir que la plus crédible est que toutes les méthodes qui conduisent a un appel de equals(Object) doivent rester avec ce type d'argument sinon l'efffacement risque de pas bien conduire au bon endroit. (voir par exemple ArrayList remove etc....).
    Il faudrait que je prenne le temps de bien vérifier le pourquoi de ce comportement.
    autre raison avancée: compatibilité avec equals entre objets de nature différentes mais ça me semble exotique.

  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
    C'est comme pour ArrayList<T> ça possède une méthode remove(Object) et non T, tout simplement parce que tu peux faire par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Object eq = new Object() {
        @Override public boolean equals(Object o) {
             return //expression;
        }
    };
    maList.remove(eq);

  4. #4
    Membre confirmé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 106
    Par défaut
    Merci pour les réponses mais on dirait qu'il y a parfois des bizarreries au niveau des generics.

    J'aurais préféré avoir la méthode V get(K key) pour que le compilateur me signale des erreurs du type suivant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Map<String, String> nameMap = new HashMap<String ,String>();
    ...
    String name = nameMap.get(un objet qui ne soit pas une String); // erreur

  5. #5
    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
    L'une de ces questions et réponses : Map.get(Object o) vs Map.get(K k) ?

  6. #6
    Membre Expert
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Par défaut
    j'ai un peu de mal à suivre.
    je comprends ceci: à l'origine un problème d'effacement de code lorsqu'il y a capture (expression en ?). bon ça je m'en doutais.
    mais apparement equals n'est pas le seul en cause il semble s'agir d'un phénomène de cohérence plus subtil lorsque des contraintes vont converger ....
    Quelqu'un peut me détailler point par point le raisonnement ? (je suis friand de ce genre de chose:il existe d'autres cas d'anomalies apparentes bien saignantes)

  7. #7
    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
    Je pense que c'est, malgré tout, un peu tiré par les cheveux.

    D'abord, Map.get ne se sert pas directement de equals, mais de la méthode hashcode() pour retrouver une clef. Puis, en cas de conflit de clef (on est déjà dans un cas moins courant ! ), alors seulement elle se sert de la méthode equals(). Et, en toutes hypothèses, il est possible que deux objets de classes différentes soient égaux entre eux. C'est un cas peu courant de chez peu courant, d'autant que normalement, dans une map il ne faut mettre comme clef que des objets immuables, mais c'est possible.

    Bref, on est dans le 1/2 millièmes de pour cent de cas possibles, mais théoriquement envisageables.

    Ma contribution à moi de 1/2 millièmes de pour cent.

  8. #8
    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 spekal
    D'abord, Map.get ne se sert pas directement de equals, mais de la méthode hashcode() pour retrouver une clef. Puis, en cas de conflit de clef (on est déjà dans un cas moins courant ! ), alors seulement elle se sert de la méthode equals().
    Non : equals() est appelé dans tout les cas car le hashCode seul ne peut pas permettre de vérifier l'égalité. Il permet seulement d'accéder plus rapidement à des objets potentiellement égaux...

    Citation Envoyé par spekal
    Et, en toutes hypothèses, il est possible que deux objets de classes différentes soient égaux entre eux. C'est un cas peu courant de chez peu courant, d'autant que normalement, dans une map il ne faut mettre comme clef que des objets immuables, mais c'est possible.
    Ben l'un n'empêche pas l'autre : deux objets de type différents peuvent être immuable et égaux entre eux...


    a++

  9. #9
    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
    J'avais posé une question similaire pour les Lists, mais après recherches, je ne retrouve plus le post...

    Depuis, je trouve pratique de pouvoir passer un objet ne redéfinissant que le equals (comme j'ai écrit ci-dessus).

    Par exemple, tu as une liste de Personnes, qui ne contient qu'un seul constructeur, qui est Personne(String nom, String prenom, Date dateNaissance, String adresse, String ville).

    Donc imagine si tu veux chercher à partir de son nom, si le type était le type générique, tu serais obligé de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    list.get(new Personne("lenom", "valeurbidon", new Date(), "valeurbidon", "valeurbidon"));
    Alors que si la méthode est get(Object), tu peux faire un objet à passer en paramètre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Object eq = new Object() {
        @Override public boolean equals(Object o) {
             return "lenomàchercher".equals(((Personne)o).getNom());
        }
    };
    De plus, tu veux avoir la possibilité de chercher une personne, selon plusieurs modes de recherche:
    - à partir de son nom
    - à partir de son nom et prénom
    - à partir de sa ville
    - etc...

    Tu ne peux donc pas utiliser la méthode equals(Object) de la classe Personne pour réaliser plusieurs modes de recherche, car le equals ne pourrait te donner au maximum qu'une de ces possibilités simultanément.




    Donc voilà pour moi les 2 raisons d'avoir fait un .get(Object)... pareil pour remove etc...

    J'ai expliqué pour les Lists, mais bien sûr c'est pareil pour les Maps...

Discussions similaires

  1. Fonction gmtmath de Generic Mapping Tools
    Par Don_Q dans le forum Linux
    Réponses: 0
    Dernier message: 06/12/2012, 11h43
  2. Réponses: 5
    Dernier message: 26/10/2011, 13h58
  3. Map et generics, ça ne passe pas
    Par DevServlet dans le forum Collection et Stream
    Réponses: 12
    Dernier message: 22/09/2011, 16h40
  4. Generic Mapping Tools
    Par md dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 13/08/2010, 10h33
  5. Pb de generics avec Map< A, List<B>>
    Par Mr. Magne dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 01/07/2008, 14h46

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