2010-04-23 7 views
6

Quel est le bon type d'argument de la méthode addAll (..) dans les collections Java? Si je fais quelque chose comme ceci:Les génériques java et la méthode addAll

List<? extends Map<String, Object[]>> currentList = new ArrayList<Map<String, Object[]>>(); 
Collection<HashMap<String, Object[]>> addAll = new ArrayList<HashMap<String, Object[]>>(); 
// add some hashmaps to the list.. 
currentList.addAll(addAll); 

Je comprends que j'ai besoin d'initialiser les deux variables. Cependant, j'obtiens une erreur de compilation (de l'éclipse):

Multiple markers at this line 
    - The method addAll(Collection<? extends capture#1-of ? extends Map<String,Object[]>>) in the type List<capture#1-of ? extends Map<String,Object[]>> is not applicable for the arguments (List<capture#2-of ? extends 
    Map<String,Object[]>>) 
    - The method addAll(Collection<? extends capture#1-of ? extends Map<String,Object[]>>) in the type List<capture#1-of ? extends Map<String,Object[]>> is not applicable for the arguments 
    (Collection<HashMap<String,Object[]>>) 

Qu'est-ce que je fais mal?

+1

Pouvez-vous modifier pour afficher vos déclarations pour 'currentList' et 'newElements'? – elduff

+0

Je pense que 'newElements' est supposé être 'addAll' J'ai corrigé le code. – Jherico

Répondre

7

Vous ne pouvez insérer instances de T dans un List<T>.

Le type List<? extends Map<X,Y>> représente une liste d'un type inconnu T qui extends Map<X,Y>. Par exemple, il pourrait représenter List<LinkedHashMap<X,Y>>. Évidemment, vous ne pouvez pas insérer un HashMap<X,Y> ordinaire dans une telle liste.

Vous voulez probablement:

List<Map<String, Object[]>> currentList; 

Ou si vous voulez être que vous pourriez faire vraiment flexible:

List<? super Map<String, Object[]>> currentList; 

qui vous permettra de faire des choses folles comme:

currentList = new ArrayList<Map<? super String, ? extends Object[]>>(); 

Vous voudrez peut-être également lire la FAQ sur les génériques d'Angelika Langer, en particulier the section about wildcards.

0

Votre question se résume essentiellement à ceci:

public static <T extends Collection<?>> void foo(T t) { 
T x = null; 
x.addAll(t); 
} 

Cela échouera avec essentiellement la même erreur que vous décrivez. Essayez quelque chose le long de ces lignes pour le réparer.

public static <T extends Collection<Y>, Y> void foo(T t) { 
T x = null; 
x.addAll(t); 
} 

Alternativement, dans votre exemple ci-dessus, vous pouvez changer

List<? extends Map<String, Object[]>> currentList; 

à

List<Map<String, Object[]>> currentList; 

Generics devient assez rapidement poilu si vous essayez de commencer à passer autour de types non spécifiés.

1

Vous ne pouvez pas appeler de méthode avec des attributs génériques dans une telle liste. Fondamentalement, ce ? extends Foo dit est "quelque chose qui s'étend Foo", mais vous ne savez pas ce que c'est quelque chose. Lorsque ce type est renvoyé, vous pouvez indiquer que la valeur renvoyée est Foo ou un sous-type. Mais pour une valeur donnée, vous ne pouvez pas que cela corresponde à ? extends Foo générique.

En bref: vous devez changer currentList déclaration ou jeter aux List (sans génériques) et de vivre avec un avertissement ou (si vous savez ce que vous faites) supprimer.

8

Remplacer extends par super.

Le addAll() lui-même prend un argument ? extends T et cela ne fonctionnera pas lorsque T est ? extends Map<K, V>. Avec le changement, il deviendra effectivement ? extends ? super Map<K, V>. Cependant, mieux vaut simplement supprimer ? extends (ou ? super). C'est superflu dans ce cas particulier. Utilisez simplement List<Map<String, Object[]>>. Le addAll() prendra alors effectivement ? extends Map<String, Object[]>>.

+0

pourquoi même déclarer le 'currentList' comme' List > ', et pas seulement' List > '? cette partie de son code me semble inutile. –

+0

@matt: C'est aussi ce que j'ai dit au dernier paragraphe :) – BalusC

6

Rappelez-vous:

pour <? extends ...>, vous ne pouvez pas mettre les choses (sauf null) dans ce

pour <? super ...>, vous ne pouvez pas faire avancer les choses (sauf objets) hors de lui