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

cette question a déjà une réponse ici:

y a-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é concernant ce. Est-ce possible? Je suis à la recherche du moyen le plus court/le plus rapide pour mettre quelques valeurs "finales/statiques" dans une carte qui ne change jamais et sont connues à l'avance lors de la création de la carte.

755
demandé sur Freedom_Ben 2011-07-23 22:40:33

6 réponses

Non, vous devez ajouter tous les éléments manuellement. Vous pouvez utiliser un initialiseur statique:

public class Demo
{
    private static final Map<String, String> myMap;
    static
    {
        myMap = new HashMap<String, String>();
        myMap.put("a", "b");
        myMap.put("c", "d");
    }
}

noter que l'utilisation d'une fonction d'initialisation fera la même chose mais pourrait améliorer la lisibilité du code:

public class Demo
{
    private static final Map<String, String> myMap = createMap();
    private static Map<String, String> createMap()
    {
        Map<String,String> myMap = new HashMap<String,String>();
        myMap.put("a", "b");
        myMap.put("c", "d");
        return myMap;
    }
}

Java 9

en Java 9, quelques méthodes factory sont ajoutées qui peuvent également être utilisées pour simplifier la création de cartes:

public class Demo {
    private static final Map<String, String> test = Map.of("a", "b", "c", "d");
    private static final Map<String, String> test2 = Map.ofEntries(
        entry("a", "b"),
        entry("c", "d")
    );
}

Dans l'exemple ci-dessus les deux 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, tandis que la méthode Map.ofEntries n'aura pas de telle 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 également JEP 269 et le Javadoc )

909
répondu yankee 2018-03-14 19:37:43

c'est un chemin.

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

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 lire plus ici: http://www.c2.com/cgi/wiki?DoubleBraceInitialization ou tout simplement utiliser la Goyave:

Map<String, Integer> left = ImmutableMap.of("a", 1, "b", 2, "c", 3);
919
répondu gregory561 2016-03-23 13:51:38

si vous autorisez les libs de tiers, vous pouvez utiliser Guava 's ImmutableMap pour atteindre la brièveté littérale:

Map<String, String> test = ImmutableMap.of("k1", "v1", "k2", "v2");

cela fonctionne pour jusqu'à 5 paires clé/valeur , sinon vous pouvez utiliser son constructeur :

Map<String, String> test = ImmutableMap.<String, String>builder()
    .put("k1", "v1")
    .put("k2", "v2")
    ...
    .build();



284
répondu Jens Hoffmann 2018-07-25 06:43:35

il n'y a pas de moyen direct de le faire - Java n'a pas de cartes littérales (encore - je pense qu'elles ont été proposées pour Java 8).

certaines personnes aiment cela:

Map<String,String> test = new HashMap<String, String>(){{
       put("test","test"); put("test","test");}};

cela crée une sous-classe anonyme de HashMap, dont l'initialiseur d'instance met ces valeurs. (En passant, une carte ne peut pas contenir deux fois la même valeur, votre deuxième mettre remplacera le premier. J'utiliserai différentes valeurs pour les prochains exemples.)

la normale comment serait ceci (pour une variable locale):

Map<String,String> test = new HashMap<String, String>();
test.put("test","test");
test.put("test1","test2");

si votre carte test est une variable d'instance, mettez l'initialisation dans un constructeur ou initialiseur d'instance:

Map<String,String> test = new HashMap<String, String>();
{
    test.put("test","test");
    test.put("test1","test2");
}

si votre carte test est une variable de classe, mettez l'initialisation dans un initialiseur statique:

static Map<String,String> test = new HashMap<String, String>();
static {
    test.put("test","test");
    test.put("test1","test2");
}

si vous voulez que votre carte ne change jamais, vous devez après l'initialisation envelopper votre carte par Collections.unmodifiableMap(...) . Vous pouvez le faire cela aussi dans un initialiseur statique:

static Map<String,String> test;
{
    Map<String,String> temp = new HashMap<String, String>();
    temp.put("test","test");
    temp.put("test1","test2");
    test = Collections.unmodifiableMap(temp);
}

(Je ne suis pas sûr si vous pouvez maintenant faire test final ... l'essayer et de signaler ici.)

88
répondu Paŭlo Ebermann 2013-06-28 21:21:27
Map<String,String> test = new HashMap<String, String>()
{
    {
        put(key1, value1);
        put(key2, value2);
    }
};
56
répondu Shaggy Frog 2011-07-23 18:47:06

une alternative, en utilisant les classes Java 7 et varargs: créer une classe HashMapBuilder avec cette méthode:

public static HashMap<String, String> build(String... data){
    HashMap<String, String> result = new HashMap<String, String>();

    if(data.length % 2 != 0) 
        throw new IllegalArgumentException("Odd number of arguments");      

    String key = null;
    Integer step = -1;

    for(String value : data){
        step++;
        switch(step % 2){
        case 0: 
            if(value == null)
                throw new IllegalArgumentException("Null key value"); 
            key = value;
            continue;
        case 1:             
            result.put(key, value);
            break;
        }
    }

    return result;
}

utilisez la méthode suivante:

HashMap<String,String> data = HashMapBuilder.build("key1","value1","key2","value2");
40
répondu Aerthel 2013-07-04 16:10:23