Come inizializzare direttamente una HashMap (in modo letterale)? [duplicato]


Questa domanda ha già una risposta qui:

C'è un modo per inizializzare una HashMap Java come questa?:

Map<String,String> test = 
    new HashMap<String, String>{"test":"test","test":"test"};

Quale sarebbe la sintassi corretta? Non ho trovato nulla al riguardo. È possibile? Sto cercando il modo più breve / veloce per inserire alcuni valori" finali/statici" in una mappa che non cambia mai e sono noti in anticipo durante la creazione della mappa.

Author: Freedom_Ben, 2011-07-23

6 answers

No, dovrai aggiungere tutti gli elementi manualmente. È possibile utilizzare un inizializzatore statico però:

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

Si noti che l'utilizzo di una funzione per l'inizializzazione farà lo stesso, ma potrebbe migliorare la leggibilità del codice:

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

In Java 9 vengono aggiunti un paio di metodi di fabbrica che possono essere utilizzati anche per semplificare la creazione di mappe:

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")
    );
}

Nell'esempio sopra sia test che test2 saranno uguali, solo con modi diversi di esprimere la Mappa. Il Il metodo Map.of è definito per un massimo di dieci elementi nella mappa, mentre il metodo Map.ofEntries non avrà tale limite.

Si noti che in questo caso la mappa risultante sarà una mappa immutabile. Se vuoi che la mappa sia mutabile, puoi copiarla di nuovo, ad esempio usando mutableMap = new HashMap<>(Map.of("a", "b"));

(vedi anche PEC 269 e Javadoc)

 909
Author: yankee, 2018-03-14 19:37:43

Questo è un modo.

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

Tuttavia, dovresti stare attento e assicurarti di aver compreso il codice sopra (crea una nuova classe che eredita da HashMap). Pertanto, dovresti leggere di più qui: http://www.c2.com/cgi/wiki?DoubleBraceInitialization , o semplicemente usi Guava:

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

Se permetti le librerie di terze parti, puoi usare Guava ' s ImmutableMap per ottenere una brevità letterale:

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

Funziona fino a 5 coppie chiave/valore, altrimenti puoi usare il suo builder:

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


  • si noti che l'implementazione ImmutableMap di Guava differisce dall'implementazione HashMap di Java (in particolare è immutabile e non consente chiavi/valori nulli)
  • per maggiori informazioni, vedi Guava articolo di guida per l'utente sui suoi tipi di raccolta immutabili
 284
Author: Jens Hoffmann, 2018-07-25 06:43:35

Non esiste un modo diretto per farlo - Java non ha letterali di mappa (ancora - penso che siano stati proposti per Java 8).

Ad alcune persone piace questo:

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

Questo crea una sottoclasse anonima di HashMap, il cui inizializzatore di istanze inserisce questi valori. (A proposito, una mappa non può contenere il doppio dello stesso valore, il tuo secondo put sovrascriverà il primo. Userò valori diversi per i prossimi esempi.)

Il modo normale sarebbe questo (per un locale variabile):

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

Se la tua mappa test è una variabile di istanza, inserisci l'inizializzazione in un costruttore o in un inizializzatore di istanza:

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

Se la tua mappa test è una variabile di classe, inserisci l'inizializzazione in un inizializzatore statico:

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

Se vuoi che la tua mappa non cambi mai, dopo l'inizializzazione dovresti avvolgere la tua mappa di Collections.unmodifiableMap(...). Puoi farlo anche in un inizializzatore statico:

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);
}

(Non sono sicuro se ora puoi fare test finale ... provalo e segnala qui.)

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

Un'alternativa, utilizzando semplici classi Java 7 e varargs: creare una classe HashMapBuilder con questo metodo:

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;
}

Usa il metodo in questo modo:

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