Question Comment initialiser directement un HashMap (d'une manière littérale)? [dupliquer]


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

Y a-t-il un moyen d'initialiser un Java HashMap comme ça?

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 / le plus rapide de mettre des valeurs "finales / statiques" dans une carte qui ne change jamais et qui est connue à l'avance lors de la création de la carte.


719
2017-07-23 18:40


origine


Réponses:


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

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

Notez que l'utilisation d'une fonction pour l'initialisation fera la même chose mais peut 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

Dans Java 9, on ajoute quelques méthodes d'usine 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 sera le même, juste avec différentes façons d'exprimer la carte. le Map.of La méthode est définie pour dix éléments maximum sur la carte, Map.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 copier à nouveau, par ex. en utilisant mutableMap = new HashMap<>(Map.of("a", "b"));

(Voir également JEP 269 et le Javadoc)


861
2017-07-23 18:44



C'est un moyen.

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 utilisez simplement Guava:

Map<String, Integer> left = ImmutableMap.of("a", 1, "b", 2, "c", 3);

888
2017-07-23 18:45



Si vous autorisez des bibliothèques tierces, vous pouvez utiliser Goyavede ImmutableMap pour obtenir une brièveté littérale:

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

Cela fonctionne 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();


  • notez que Guava's ImmutableMap la mise en œuvre diffère de Java HashMap implémentation (le plus notable est immuable et n'autorise pas les clés / valeurs nulles)
  • Pour plus d'informations, consultez l'article du guide de l'utilisateur de Guava sur types de collection immuables

268
2018-06-28 22:03



Il n'y a pas de moyen direct de le faire - Java n'a pas de littéraux Map (encore - je pense qu'ils ont été proposés pour Java 8).

Certaines personnes aiment ça:

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'initialisateur d'instance place ces valeurs. (Au fait, une carte ne peut pas contenir deux fois la même valeur, votre deuxième put remplacera la première.Je vais utiliser des valeurs différentes pour les prochains exemples.)

La manière normale serait ceci (pour une variable locale):

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

Si ton test map est une variable d'instance, placez l'initialisation dans un constructeur ou un initialiseur d'instance:

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

Si ton test map 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 devriez après l'initialisation envelopper votre carte par Collections.unmodifiableMap(...). Vous pouvez le faire dans un initialiseur statique aussi:

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 ... essayer et rapporter ici.)


87
2017-07-23 18:48



Map<String,String> test = new HashMap<String, String>()
{
    {
        put(key1, value1);
        put(key2, value2);
    }
};

53
2017-07-23 18:47



Une alternative, en utilisant des classes Java 7 simples 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 comme ceci:

HashMap<String,String> data = HashMapBuilder.build("key1","value1","key2","value2");

39
2017-07-04 16:10