63 votes

Comment initialiser correctement une HashMap et la HashMap peut-elle contenir différents types de valeurs ?

J'ai donc deux questions à poser HashMap en Java :

  1. Quelle est la bonne façon d'initialiser un HashMap ? Je pense qu'il serait préférable de l'utiliser dans ma situation :

    HashMap x = new HashMap();

    Mais Eclipse continue de me suggérer d'utiliser :

    HashMap<something, something> map = new HashMap();

    Quelle est la meilleure solution ?

  2. Est-ce qu'un HashMap contenir différents types d'objets/types de données en tant que valeurs ? Par exemple, est-ce que cela fonctionnerait et serait acceptable ?

    map.put("one", 1);
    map.put("two", {1, 2});
    map.put("three", "hello");

    Dans la première put() Je veux un int comme valeur, dans le second un int[] et le troisième une corde. Est-il possible de faire cela en Java avec HashMap s ? De même, est-il possible de stocker un HashMap en tant que valeur à l'intérieur d'un HashMap ?

104voto

Yishai Points 42417

Tout dépend du type de sécurité dont vous avez besoin. La façon non générique de procéder est la suivante :

 Map x = new HashMap();

Il convient de noter que x est typée comme un Map . cela facilite grandement les changements de mise en œuvre (vers une TreeMap ou un LinkedHashMap ) à l'avenir.

Vous pouvez utiliser des génériques pour garantir un certain niveau de sécurité des types :

Map<String, Object> x = new HashMap<String, Object>();

Dans Java 7 et les versions ultérieures, vous pouvez faire

Map<String, Object> x = new HashMap<>();

La méthode ci-dessus, bien que plus verbeuse, permet d'éviter les avertissements du compilateur. Dans ce cas, le contenu du fichier HashMap peut être n'importe quel Object , de sorte que l'on peut Integer , int[] etc., ce que vous êtes en train de faire.

Si vous utilisez encore Java 6, Bibliothèques de goyave (bien qu'il soit assez facile de le faire soi-même) possède une méthode appelée newHashMap() ce qui évite d'avoir à dupliquer les informations de typage générique lorsque l'on fait un new . Il déduit le type à partir de la déclaration de la variable (il s'agit d'une fonctionnalité de Java qui n'était pas disponible pour les constructeurs avant Java 7).

D'ailleurs, lorsque vous ajoutez un int ou une autre primitive, Java l'autoboxe. Cela signifie que le code est équivalent à :

 x.put("one", Integer.valueOf(1));

Vous pouvez certainement mettre un HashMap comme valeur dans un autre HashMap mais je pense qu'il y a des problèmes si vous le faites de manière récursive (c'est-à-dire que vous mettez le HashMap comme une valeur en soi).

1 votes

Quelle est la différence entre faire une HashMap<String, Object> map = new... et Map<String, Object> map = new... ? Ou s'agit-il de la même chose ?

5 votes

Ils font la même chose, c'est juste que votre référence est typée comme une Map (l'interface) au lieu d'une HashMap (l'implémentation) afin que l'implémentation puisse être facilement modifiée sans affecter plus d'une ligne de code.

0 votes

Regardez la réponse de Basile. Map.of() est le meilleur moyen pour une liste statique de quelques éléments, ayant un initialisateur dans l'appel.

14voto

MBCook Points 8316

Il s'agit d'une modification apportée par Java 1.5. La première liste est l'ancienne méthode, la seconde est la nouvelle.

En utilisant HashMap, vous pouvez faire des choses comme :

HashMap<String, Doohickey> ourMap = new HashMap<String, Doohickey>();

....

Doohickey result = ourMap.get("bob");

Si vous n'avez pas les types sur la carte, vous devez procéder ainsi :

Doohickey result = (Doohickey) ourMap.get("bob");

C'est vraiment très utile. Il vous aide à détecter les bogues et à éviter d'écrire toutes sortes de casts supplémentaires. C'était l'une de mes fonctionnalités préférées de la version 1.5 (et des versions plus récentes).

Vous pouvez toujours mettre plusieurs choses dans la carte, il suffit de la spécifier en tant que carte, puis vous pouvez y mettre n'importe quel objet (une chaîne, une autre carte, un entier et trois MyObjects si vous êtes si enclin).

3 votes

Vous m'avez eu jusqu'au dernier paragraphe. Les "listes avec un petit 'l'" s'appellent des tableaux ; et ce sont très certainement des objets en Java.

0 votes

Vous indiquez que pour mettre plusieurs choses dans la carte, je devrais simplement la spécifier en tant que carte. Pourquoi ne pourrais-je pas utiliser HashMap ?

0 votes

@ChssPly76 : "arrays". C'est le terme. Je n'arrivais pas à m'en souvenir et j'ai opté pour ma meilleure supposition du moment. Merci beaucoup.

4voto

Paul Tomblin Points 83687

Eclipse recommande de déclarer le type de la HashMap car cela permet d'assurer une certaine sécurité de type. Bien sûr, il semble que vous essayez d'éviter la sécurité de type dans votre deuxième partie.

Si vous voulez faire cela, essayez de déclarer map en tant que HashMap<String,Object> .

0 votes

Un int est-il considéré comme un objet ?

0 votes

Les "int" ne sont pas des objets, c'est un type primitif. Toutes les primitives (int, double, long, short...) ont une version objet que vous pouvez utiliser (Integer, Double, Long, Short). Java 1.5+ fera même la conversion entre int et Integer pour vous afin que vous n'ayez pas à vous en soucier (la plupart du temps, cherchez "autoboxing").

0 votes

Autoboxing convertira int[] en Object.

3voto

Graphics Noob Points 4004

La façon dont vous l'écrivez équivaut à

HashMap<Object, Object> map = new HashMap<Object, Object>();

Ce qui se trouve entre les crochets, c'est que vous communiquez au compilateur ce que vous allez mettre dans le HashMap afin qu'il puisse faire le contrôle d'erreur pour vous. Si Object, Object est ce que vous voulez réellement (probablement pas), vous devez le déclarer explicitement. En général, vous devriez être aussi explicite que possible avec la déclaration pour faciliter la vérification des erreurs par le compilateur. Ce que vous avez décrit devrait probablement être déclaré comme ceci :

HashMap<String, Object> map = new HashMap<String, Object>();

De cette façon, vous déclarez au moins que vos clés seront des chaînes, mais que vos valeurs peuvent être n'importe quoi. N'oubliez pas d'utiliser un cast lorsque vous récupérez une valeur.

2voto

Billy Bob Bain Points 2069

La deuxième est l'utilisation des génériques qui sont apparus avec Java 1.5. Cela réduira le nombre de casts dans votre code et peut vous aider à détecter les erreurs au moment de la compilation plutôt qu'au moment de l'exécution. Cela dit, tout dépend de ce que vous codez. Une carte rapide et sale pour contenir quelques objets de différents types n'a pas besoin de génériques. Mais si la carte contient des objets qui descendent tous d'un type autre que Object, cela peut en valoir la peine.

L'affiche précédente est incorrecte en ce qui concerne le tableau dans une carte. Un tableau est en fait un objet, c'est donc une valeur valide.

Map<String,Object> map = new HashMap<String,Object>();
map.put("one",1); // autoboxed to an object
map.put("two", new int[]{1,2} ); // array of ints is an object
map.put("three","hello"); // string is an object

De plus, puisque HashMap est un objet, il peut également s'agir d'une valeur dans un HashMap.

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