Je peux déclarer un tableau de cartes en utilisant des génériques pour spécifier le type de carte:
private Map<String, Integer>[] myMaps;
Cependant, je ne sais pas comment l'instancier correctement:
myMaps = new HashMap<String, Integer>[count]; // gives "generic array creation" error
myMaps = new HashMap[count]; // gives an "unchecked or unsafe operation" warning
myMaps = (Map<String, Integer>[])new HashMap[count]; // also gives warning
Comment puis-je instancier ce tableau de cartes sans obtenir d'erreur ou d'avertissement du compilateur?
Mise à jour:
Merci à tous pour vos réponses. J'ai fini par accepter la suggestion de liste.
Pas strictement une réponse à votre question, mais avez-vous envisagé d'utiliser un List
à la place?
List<Map<String,Integer>> maps = new ArrayList<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());
semble fonctionner très bien.
Voir Théorie et pratique Java: gotchas génériques pour une explication détaillée des raisons pour lesquelles le mélange de tableaux avec des génériques est déconseillé.
Comme mentionné par Drew dans les commentaires, il pourrait être encore mieux d'utiliser l'interface Collection au lieu de List
. Cela peut être utile si vous avez besoin de passer à un Set
, ou à l'une des autres sous-interfaces de Collection
. Exemple de code:
Collection<Map<String,Integer>> maps = new HashSet<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());
À partir de ce point de départ, il vous suffit de remplacer HashSet
par ArrayList
, PriorityQueue
ou toute autre classe qui implémente Collection
.
Vous ne pouvez pas créer en toute sécurité un tableau générique. Efficace Java 2nd Edition va dans les détails dans le chapitre sur les génériques . Commencez par le dernier paragraphe de la page 119:
Pourquoi est-il illégal de créer un tableau générique? Parce que ce n'est pas sûr pour les types. S'il était légal, les conversions générées par le compilateur dans un programme par ailleurs correct pourraient échouer lors de l'exécution avec un
ClassCastException
. Cela violerait la garantie fondamentale fournie par le système de type générique.Pour rendre cela plus concret, considérez le fragment de code suivant:
// Why generic array creation is illegal - won't compile! List<String>[] stringLists = new List<String>[1]; // (1) List<Integer> intList = Arrays.asList(42); // (2) Object[] objects = stringLists; // (3) objects[0] = intList; // (4) String s = stringLists[0].get(0); // (5)
Imaginons que la ligne 1, qui crée un tableau générique, est légale. La ligne 2 crée et initialise un
List<Integer>
contenant un seul élément. La ligne 3 stocke leList<String>
array dans une variable de tableauObject
, ce qui est légal car les tableaux sont covariants. La ligne 4 stocke leList<Integer>
dans le seul élément du tableauObject
, qui réussit car les génériques sont implémentés par effacement: le type d'exécution d'unList<Integer>
instance est simplementList
, et le type d'exécution d'unList<String>[]
l'instance estList[]
, donc cette affectation ne génère pas deArrayStoreException
. Maintenant, nous avons des ennuis. Nous avons stocké unList<Integer>
instance dans un tableau qui est déclaré contenir uniquementList<String>
instances. À la ligne 5, nous récupérons l'élément unique de la liste unique de ce tableau. Le compilateur convertit automatiquement l'élément récupéré enString
, mais c'est unInteger
, donc nous obtenons unClassCastException
au moment de l'exécution. Afin d'éviter cela, la ligne 1 (qui crée un tableau générique) génère une erreur de compilation.
Parce que les tableaux et les génériques ne se combinent pas bien (ainsi que d'autres raisons), il est généralement préférable d'utiliser Collection
objets (en particulier List
objets) plutôt que des tableaux.
En général, ce n'est pas une bonne idée de mélanger des génériques et des tableaux en Java, mieux vaut utiliser une ArrayList.
Si vous devez utiliser un tableau, la meilleure façon de gérer cela est de placer la création du tableau (votre exemple 2 ou 3) dans une méthode distincte et de l'annoter avec @SuppressWarnings ("non vérifiée").
La réponse courte semble être que vous ne pouvez vraiment pas.
Voir ce qui suit pour un blog à ce sujet. http://www.bloggingaboutjava.org/2006/01/Java-generics-quirks/
L'un des commentaires du blog indique que:
En fait, les ingénieurs ont rendu illégale la création d'un tel tableau. La création d'un tableau à partir d'une classe générique échoue donc. La méthode Collection.toArray suivie d'un Cast to the Array fonctionne au moment de la compilation.
Cela ne résout pas le problème, à savoir que ArrayStoreCheck ne peut pas être effectué pendant l'exécution, mais vous pouvez créer un tableau de génériques de cette manière.
Comme l'a suggéré Bill le Lézard, vous feriez probablement mieux d'utiliser un
List<Map<String,Integer>>