Come inizializzare direttamente una HashMap (in modo letterale)?

C'è un modo per inizializzare una HashMap Java in questo modo?

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

Quale sarebbe la sintassi corretta? Non ho trovato nulla riguardo a questo. È possibile? Sto cercando il modo più breve/veloce per mettere alcuni valori "final/static" in una mappa che non cambiano mai e sono conosciuti in anticipo quando si crea la mappa.

Soluzione

Per Java versione 9 o superiore:

Sì, questo è possibile ora. In Java 9 sono stati aggiunti un paio di metodi factory che semplificano la creazione di mappe:

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

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

Nota che in questo caso la mappa risultante sarà una mappa immutabile. Se volete che la mappa sia mutabile, potreste copiarla di nuovo, ad esempio usando mutableMap = new HashMap(Map.of("a", "b"));

(Vedere anche JEP 269 e il Javadoc)

Fino alla versione 8 di Java:

No, dovrete aggiungere tutti gli elementi manualmente. Puoi usare un inizializzatore in una sottoclasse anonima per rendere la sintassi un po' più breve:

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

Tuttavia, la sottoclasse anonima potrebbe introdurre comportamenti indesiderati in alcuni casi. Questo include per esempio:

  • Genera una classe aggiuntiva che aumenta il consumo di memoria, il consumo di spazio su disco e il tempo di avvio
  • Nel caso di un metodo non statico: Tiene un riferimento all'oggetto su cui è stato chiamato il metodo di creazione. Ciò significa che l'oggetto della classe esterna non può essere smaltito mentre l'oggetto della mappa creata è ancora referenziato, bloccando così ulteriore memoria

Usare una funzione per l'inizializzazione vi permetterà anche di generare una mappa in un inizializzatore, ma evita brutti effetti collaterali:

Map myMap = createMap();

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

Questo è un modo.

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

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

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