148 votes

Pourquoi aren ' t Java Collections supprimer les méthodes génériques ?

Pourquoi Collection.remove (Object o) n’est pas générique ?

On dirait pourrait avoir

Ensuite, lorsque vous essayez accidentellement supprimer (par exemple) au lieu de chaque chaîne individuelle d’un , ce serait une erreur de compilation au lieu d’un problème de débogage plus tard.

76voto

newacct Points 42530

remove() (en Map ainsi que dans Collection) n'est pas générique, car vous devez être en mesure de passer dans n'importe quel type d'objet remove(). L'objet enlevé n'a pas à être le même type que l'objet que vous passez en remove(); il exige seulement qu'ils soient égaux. De la spécification d' remove(), remove(o) supprime l'objet e tels que (o==null ? e==null : o.equals(e)) est vrai. Notez qu'il n'y a rien exiger o et e doit être du même type. Cela découle du fait que l' equals() méthode prend un Objet en paramètre, pas seulement le même type que l'objet.

Bien qu'il puisse être vrai que de nombreuses classes ont equals() défini de telle sorte que ses objets ne peuvent être égaux aux objets de sa propre classe, qui n'est certainement pas toujours le cas. Par exemple, le cahier des charges pour la Liste.equals() affirme que les deux objets de la Liste sont égales si elles sont à la fois des Listes et ont le même contenu, même si elles sont différentes implémentations de la Liste. Afin de revenir à l'exemple de cette question, il est possible d'avoir un Map<ArrayList, Something> et pour moi d'appeler remove() avec un LinkedList comme argument, et il faut supprimer la clé, qui est une liste avec le même contenu. Ce ne serait pas possible si remove() sont génériques et restreint son type d'argument.

75voto

dmeister Points 11529

Josh Bloch et le projet de Loi Pugh, reportez-vous à cette question dans "Java casse-têtes IV: La Fantôme de Référence de la Menace, de l'Attaque des clones et La revanche de l' Shift" (Google TechTalk).

Josh Bloch dit (6:41) qu'ils ont tenté de generify la méthode get de la Carte, suppression de la méthode et quelques autres, mais "il n'a tout simplement pas de travail". Il y a trop raisonnable des programmes qui pourraient ne pas être si generified autoriser uniquement le type générique de la collection comme type de paramètre. L'exemple donné est une intersection d'une Liste de Numéros et d'un Liste des Longs.

11voto

firebird84 Points 767

Parce que si votre paramètre de type est un générique, vous ne pouvez pas utiliser un générique de supprimer la méthode.

Je me souviens de la question avec Carte du get(Object) de la méthode. La méthode get dans ce cas n'est pas générique, mais il doit raisonnablement s'attendre à être passé un objet du même type que le premier paramètre de type. J'ai réalisé que si vous êtes de passage sur les Cartes avec un caractère générique comme le premier paramètre de type, alors il n'y a aucun moyen d'obtenir un élément de la Carte avec cette méthode, si cet argument était générique. Générique arguments ne peuvent pas vraiment être satisfait, car le compilateur ne peut pas garantir que le type est correct. Je suppose que la raison pour laquelle ajouter est générique, c'est que vous êtes tenus de garantir que le type est correct avant de l'ajouter à la collection. Cependant, lors de la suppression d'un objet, si le type est incorrect alors il ne correspond pas à quelque chose de toute façon. Si l'argument était d'un caractère générique de la méthode serait tout simplement inutilisable, même si vous avez un objet que vous pouvez GARANTIR appartient à la collection, parce que vous venez de recevoir une référence dans la ligne précédente....

Je n'a sans doute pas très bien l'expliquer, mais il semble assez logique pour moi.

6voto

Hosam Aly Points 14797

Outre les autres réponses, il y a une autre raison pour laquelle la méthode devrait accepter une `` , c'est-à-dire les prédicats. Considérez l’exemple suivant :

Le point est que l’objet est passé à la méthode est chargée de définir le méthode. Prédicats de construction devient très simple de cette façon.

5voto

supercat Points 25534

Supposons que l'un a une collection d' Cat, et certaines références à des objets de types Animal, Cat, SiameseCat, et Dog. Demander à la collecte si elle contient de l'objet visé par l' Cat ou SiameseCat référence semble raisonnable. En demandant s'il contient l'objet visé par l' Animal référence peut paraître louche, mais ça reste tout à fait raisonnable. L'objet en question pourrait, après tout, être un Cat, et peut apparaître dans la collection.

De plus, même si l'objet se trouve être autre chose qu'un Cat, il n'y a pas de problème en disant qu'il figure dans la collection--il vous suffit de répondre "non, ce n'est pas". Une "recherche de style" collection d'un certain type devrait être capable de véritablement accepter le renvoi de tout supertype et de déterminer si l'objet existe dans la collection. Si le passé-de l'objet de référence est d'un autre type, il n'y a aucun moyen de la collecte pourrait éventuellement contenir, de sorte que la requête est dans un certain sens, pas de sens (il sera toujours répondre "non"). Néanmoins, puisqu'il n'y a pas un moyen pour limiter les paramètres à être sous-types ou aux supertypes, il est plus pratique de tout simplement accepter tout type et de répondre "non" pour tous les objets dont le type n'est pas liée à celle de la collection.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X