Existe-t-il un moyen d'initialiser un HashMap Java comme celui-ci?:
Map<String,String> test =
new HashMap<String, String>{"test":"test","test":"test"};
Quelle serait la syntaxe correcte? Je n'ai rien trouvé à ce sujet. Est-ce possible? Je recherche le moyen le plus court / le plus rapide de mettre des valeurs "finales / statiques" dans une carte qui ne changent jamais et qui sont connues à l'avance lors de la création de la carte.
Réponses:
Toutes les versions
Au cas où vous auriez besoin d'une seule entrée: Oui
Collections.singletonMap("key", "value")
.Pour Java version 9 ou supérieure:
Oui, c'est possible maintenant. Dans Java 9, quelques méthodes d'usine ont été ajoutées pour simplifier la création de cartes:
Dans l'exemple ci-dessus les deux
test
ettest2
seront les mêmes, juste avec différentes manières d'exprimer la carte. LaMap.of
méthode est définie pour jusqu'à dix éléments dans la carte, tandis que laMap.ofEntries
méthode n'aura pas une telle limite.Notez que dans ce cas, la carte résultante sera une carte immuable. Si vous souhaitez que la carte soit modifiable, vous pouvez la recopier, par exemple en utilisant
mutableMap = new HashMap<>(Map.of("a", "b"));
(Voir aussi JEP 269 et Javadoc )
Jusqu'à Java version 8:
Non, vous devrez ajouter tous les éléments manuellement. Vous pouvez utiliser un initialiseur dans une sous-classe anonyme pour raccourcir un peu la syntaxe:
Cependant, la sous-classe anonyme peut introduire un comportement indésirable dans certains cas. Cela comprend par exemple:
L'utilisation d'une fonction d'initialisation vous permettra également de générer une carte dans un initialiseur, mais évite les effets secondaires désagréables:
la source
Collections.singletonMap()
:)entry
documenté?C'est une façon.
Cependant, vous devez être prudent et vous assurer que vous comprenez le code ci-dessus (il crée une nouvelle classe qui hérite de HashMap). Par conséquent, vous devriez en savoir plus ici: http://www.c2.com/cgi/wiki?DoubleBraceInitialization , ou simplement utiliser Guava:
la source
Si vous permettez libs 3ème partie, vous pouvez utiliser goyave de ImmutableMap pour atteindre la brièveté comme littérale:
Cela fonctionne jusqu'à 5 paires clé / valeur , sinon vous pouvez utiliser son générateur :
la source
Il n'y a aucun moyen direct de le faire - Java n'a pas de littéraux de carte (pourtant - je pense qu'ils ont été proposés pour Java 8).
Certaines personnes aiment ça:
Cela crée une sous-classe anonyme de HashMap, dont l'initialiseur d'instance place ces valeurs. (Soit dit en passant, une carte ne peut pas contenir deux fois la même valeur, votre deuxième put remplacera la première. J'utiliserai des valeurs différentes pour les exemples suivants.)
La façon normale serait la suivante (pour une variable locale):
Si votre
test
carte est une variable d'instance, placez l'initialisation dans un constructeur ou un initialiseur d'instance:Si votre
test
carte est une variable de classe, placez l'initialisation dans un initialiseur statique:Si vous souhaitez que votre carte ne change jamais, vous devez, après l'initialisation, envelopper votre carte par
Collections.unmodifiableMap(...)
. Vous pouvez également le faire dans un initialiseur statique:(Je ne sais pas si vous pouvez maintenant rendre la version
test
finale ... essayez-la et faites un rapport ici.)la source
la source
HashMap
cette sous-classe. Cela ne peut fonctionner que si vous les fournissez réellement. (Avec un nouveau HashMap (vide), les arguments de type ne sont pas pertinents.)Une alternative, en utilisant des classes et varargs Java 7 simples: créez une classe
HashMapBuilder
avec cette méthode:Utilisez la méthode comme ceci:
la source
tl; dr
Utilisez des
Map.of…
méthodes dans Java 9 et versions ultérieures.Map.of
Java 9 a ajouté une série de
Map.of
méthodes statiques pour faire exactement ce que vous voulez: Instancier une immuable enMap
utilisant une syntaxe littérale .La carte (une collection d'entrées) est immuable, vous ne pouvez donc pas ajouter ou supprimer d'entrées après l'instanciation. De plus, la clé et la valeur de chaque entrée sont immuables et ne peuvent pas être modifiées. Voir le Javadoc pour d'autres règles, telles qu'aucune valeur NULL autorisée, aucune clé en double autorisée et l'ordre d'itération des mappages est arbitraire.
Examinons ces méthodes, en utilisant des exemples de données pour une carte du jour de la semaine pour une personne qui, selon nous, travaillera ce jour-là.
Map.of()
Map.of
crée un videMap
. Non modifiable, vous ne pouvez donc pas ajouter d'entrées. Voici un exemple d'une telle carte, vide sans entrées.Map.of( … )
Map.of( k , v , k , v , …)
sont plusieurs méthodes qui prennent 1 à 10 paires clé-valeur. Voici un exemple de deux entrées.Map.ofEntries( … )
Map.ofEntries( Map.Entry , … )
prend n'importe quel nombre d'objets implémentant l'Map.Entry
interface. Java regroupe deux classes implémentant cette interface, l'une mutable, l'autre immuable:AbstractMap.SimpleEntry
,AbstractMap.SimpleImmutableEntry
. Mais nous n'avons pas besoin de spécifier une classe concrète. Nous avons simplement besoin d'appeler laMap.entry( k , v )
méthode, de passer notre clé et notre valeur, et nous récupérons un objet d'une certaineMap.Entry
interface d' implémentation de classe .Map.copyOf
Java 10 a ajouté la méthode
Map.copyOf
. Passez une carte existante, récupérez une copie immuable de cette carte.Remarques
Notez que l'ordre des itérateurs des cartes produites via ne
Map.of
sont pas garanti. Les entrées ont un ordre arbitraire. N'écrivez pas de code basé sur la commande vue, car la documentation prévient que la commande est susceptible de changer.Notez que toutes ces
Map.of…
méthodes renvoient unMap
d' une classe non spécifiée . La classe concrète sous-jacente peut même varier d'une version de Java à une autre. Cet anonymat permet à Java de choisir parmi diverses implémentations, quelle que soit celle qui correspond de manière optimale à vos données particulières. Par exemple, si vos clés proviennent d'une énumération , Java peut utiliser unEnumMap
sous les couvertures.la source
Vous pouvez éventuellement créer votre propre
Map.of
méthode (qui n'est disponible que dans Java 9 et supérieur) facilement de 2 manières simplesFaites-le avec une quantité définie de paramètres
Exemple
Faites-le en utilisant une liste
Vous pouvez également faire cela en utilisant une liste, au lieu de faire beaucoup de méthodes pour un certain ensemble de paramètres.
Exemple
Remarque Il n'est pas recommandé de l'utiliser pour tout car cela crée une classe anonyme à chaque fois que vous l'utilisez.
la source
JAVA 8
Dans plain java 8, vous avez également la possibilité d'utiliser
Streams/Collectors
pour faire le travail.Cela a l'avantage de ne pas créer de classe anonyme.
Notez que les importations sont:
Bien sûr, comme indiqué dans d'autres réponses, dans java 9 et versions ultérieures, vous avez des moyens plus simples de faire de même.
la source
Malheureusement, l'utilisation de varargs si le type des clés et des valeurs n'est pas le même n'est pas très raisonnable car vous devrez utiliser
Object...
et perdre complètement la sécurité du type. Si vous voulez toujours créer par exemple unMap<String, String>
, atoMap(String... args)
serait bien sûr possible, mais pas très joli car il serait facile de mélanger les clés et les valeurs, et un nombre impair d'arguments ne serait pas valide.Vous pouvez créer une sous-classe de HashMap qui a une méthode chaînable comme
et l'utiliser comme
new ChainableMap<String, Object>().set("a", 1).set("b", "foo")
Une autre approche consiste à utiliser le modèle de générateur commun:
et l'utiliser comme
new MapBuilder<String, Object>().put("a", 1).put("b", "foo").build();
Cependant, la solution que j'ai utilisée de temps en temps utilise des varargs et la
Pair
classe:Map<String, Object> map = Maps.of(Pair.create("a", 1), Pair.create("b", "foo");
La verbosité de
Pair.create()
me dérange un peu, mais cela fonctionne très bien. Si cela ne vous dérange pas les importations statiques, vous pouvez bien sûr créer une aide:Map<String, Object> map = Maps.of(p("a", 1), p("b", "foo");
(Au lieu de
Pair
l'imaginerMap.Entry
, mais comme il s'agit d'une interface, elle nécessite une classe d'implémentation et / ou une méthode d'usine d'assistance. Elle n'est pas non plus immuable et contient une autre logique non utile pour cette tâche.)la source
Vous pouvez utiliser Streams In Java 8 (c'est un exemple de Set):
Réf: https://www.baeldung.com/java-double-brace-initialization
la source
Si vous devez placer une seule paire clé-valeur, vous pouvez utiliser Collections.singletonMap (clé, valeur);
la source