Comment initialiser directement un HashMap (de manière littérale) ?

Existe-t-il un moyen d'initialiser un HashMap Java comme ceci ?

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 cherche le moyen le plus court/rapide de mettre dans une carte des valeurs "définitives/statiques" qui ne changent jamais et qui sont connues à l'avance lors de la création de la carte.

Solution

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 :

// this works for up to 10 elements:
Map test1 = Map.of(
    "a", "b",
    "c", "d"
);

// this works for any number of elements:
Map test2 = Map.ofEntries(
    entry("a", "b"),
    entry("c", "d")
);

Dans l'exemple ci-dessus, test et test2 seront les mêmes, mais avec des façons différentes d'exprimer la carte. La méthode Map.of est définie pour un maximum de dix éléments dans la carte, alors que la méthode Map.ofEntries n'aura pas cette limite.

Notez que dans ce cas, la carte résultante sera une carte immuable. Si vous voulez que la carte soit mutable, vous pouvez la recopier, par exemple en utilisant mutableMap = new HashMap(Map.of("a", "b"));

(Voir aussi JEP 269 et la Javadoc)

Jusqu'à la version 8 de Java :

Non, vous devrez ajouter tous les éléments manuellement. Vous pouvez utiliser un initialisateur dans une sous-classe anonyme pour rendre la syntaxe un peu plus courte :

Map myMap = new HashMap() {{
        put("a", "b");
        put("c", "d");
    }};

Cependant, la sous-classe anonyme peut introduire un comportement indésirable dans certains cas. Il s'agit par exemple de :

  • Elle génère une classe supplémentaire qui augmente la consommation de mémoire, d'espace disque et le temps de démarrage.
  • Dans le cas d'une méthode non statique : Elle détient une référence à l'objet sur lequel la méthode de création a été appelée. Cela signifie que l'objet de la classe externe ne peut pas être mis au rebut alors que l'objet de la carte créée est toujours référencé, bloquant ainsi de la mémoire supplémentaire.

L'utilisation d'une fonction pour l'initialisation vous permettra également de générer une carte dans un initialisateur, mais évite les effets secondaires désagréables :

Map myMap = createMap();

private static Map createMap() {
    Map myMap = new HashMap();
    myMap.put("a", "b");
    myMap.put("c", "d");
    return myMap;
}
Commentaires (13)

C'est une façon de faire.

HashMap h = new HashMap() {{
    put("a","b");
}};

Cependant, vous devez faire attention 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 lire plus ici : http://www.c2.com/cgi/wiki?DoubleBraceInitialization ou simplement utiliser Guava :

Map left = ImmutableMap.of("a", 1, "b", 2, "c", 3);
Commentaires (13)
Map test = new HashMap()
{
    {
        put(key1, value1);
        put(key2, value2);
    }
};
Commentaires (8)