45 votes

Comment instancier un tableau de cartes en Java?

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 peux pas comprendre 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.

47voto

Bill the Lizard Points 147311

Pas strictement une réponse à votre question, mais avez-vous songé à utiliser un List à la place?

List<Map<String,Integer>> maps = new ArrayList<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());

semble très bien fonctionner.

Voir Java la théorie et la pratique: les Génériques de pièges pour une explication détaillée des raisons de mélange des tableaux avec des génériques est découragé.

Mise à jour:

Comme mentionné par Drew dans les commentaires, il pourrait être encore mieux d'utiliser la Collection de l'interface au lieu de List. Cela pourrait être utile si jamais vous avez besoin de changer une Set, ou l'un 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>());

De ce point de départ, tu avais besoin de changer d' HashSet de ArrayList, PriorityQueue, ou de toute autre classe qui implémente Collection.

26voto

Laurence Gonsalves Points 50783

Vous ne pouvez pas sûre créer un générique de tableau. Efficace Java 2nd Edition goe dans les détails dans le chapitre sur les médicaments Génériques. Commencer au dernier paragraphe de la page 119:

Pourquoi est-il illégal de créer un générique tableau? Car il n'est pas typesafe. Si il était légal, jette généré par l' compilateur dans un ailleurs tout à fait corrects le programme peut échouer lors de l'exécution avec un ClassCastException. Ce serait violer la garantie fournie par le type générique du système.

Pour rendre cela plus concret, considérons 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 generic array, est légal. Ligne 2 crée et initialise une La liste ne contenant qu'un seul de l'élément. Ligne 3 magasins de la Liste de tableau dans un Objet variable de tableau, ce qui est légal car les tableaux sont covariants. Ligne 4 magasins la Liste dans la semelle élément de l'Objet array, qui réussit parce que les génériques sont mis en œuvre par l'effacement: le moteur d'exécution le type d'une instance de Liste est tout simplement la Liste, et le runtime type de Liste[] de l'instance est la Liste[], donc cette mission n'est pas de générer une ArrayStoreException. Maintenant, nous sommes dans de la difficulté. Nous avons stocké une Liste exemple dans un tableau qui est déclaré à détenir qu'Liste les instances. Dans la ligne 5, nous récupérons les seul élément à partir de la seule liste dans de ce tableau. Le compilateur automatiquement jette l'extrait élément de Chaîne, mais c'est un Entier, on obtient donc un ClassCastException au moment de l'exécution. Dans afin d'éviter que cela se produise, la ligne 1 (qui crée un generic array) génère une erreur de compilation.

Car les tableaux et les génériques ne combinent pas bien (ainsi que d'autres raisons), il est généralement préférable d'utiliser des Collections (en particulier, les Listes) plutôt que les tableaux.

6voto

starblue Points 29696

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").

2voto

RHSeeger Points 9217

Bref, la réponse semble être que vous avez vraiment ne peut pas juste.

Consultez la rubrique suivante pour un blog à ce sujet. http://www.bloggingaboutjava.org/2006/01/java-generics-quirks/

L'un des commentaires sur le blog, qui stipule que:

En fait, les ingénieurs ont fait de la création d'une telle Matrice illégale. Donc, la création d'un tableau de Classe générique échoue. La Collecte.toArray méthode suivie par une Fonte de la Matrice au moment de la compilation.

Cela résout pas le problème, que le ArrayStoreCheck ne peut pas être fait au cours de l'Exécution, mais vous pouvez créer un Tableau de génériques de cette façon.

Comme suggéré par Bill le Lézard, vous êtes probablement mieux d'utiliser un

List<Map<String,Integer>>

-2voto

Steve B. Points 23227

J'avais une question similaire , meilleure réponse, je me suis référé à cette

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