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
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
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.
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);
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
L'une de ces questions et réponses : Map.get(Object o) vs Map.get(K k) ?
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)
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.
Salut,
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...Envoyé par spekal
Ben l'un n'empêche pas l'autre : deux objets de type différents peuvent être immuable et égaux entre eux...Envoyé par spekal
a++
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
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 list.get(new Personne("lenom", "valeurbidon", new Date(), "valeurbidon", "valeurbidon"));
De plus, tu veux avoir la possibilité de chercher une personne, selon plusieurs modes de recherche:
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()); } };
- à 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...
Partager