2011-01-30 1 views
9

Mi stavo chiedendo se è possibile definire il contenuto di un oggetto mappa all'inizializzazione.Come definire i contenuti della mappa sull'inizializzazione?

Ad esempio, un array possono essere creati, come:

new String[] {“apples”, “bananas”, “pears”} 

Così, mi chiedevo se c'è qualcosa di simile si può fare per le mappe.

+2

Strettamente legato: http://stackoverflow.com/questions/507602/how-to-init ialise-a-static-map-in-java? rq = 1 – Jonik

risposta

24

È possibile, una sorta di, utilizzando questa sintassi trucco:

Map<String,String> map = new HashMap<String,String>() {{ 
    put("x", "y"); 
    put("a", "b"); 
}}; 

Non molto piacevole, però. Questo crea una sottoclasse anonima di HashMap e la popola nell'inizializzatore di istanza.

+0

Bel trucco. Metterei quelle interne {} su linee separate, però, dato che ora sembra molto confuso. –

+0

@Sergey: certo, qualunque sia lo stile che preferisci. Ho sempre usato questo stile, però, e ogni volta che vedo questo trucco usato, usa anche questo stile. Ti ci abitui. L'importante è l'inizializzatore, è quello su cui dovrebbe concentrarsi. – skaffman

+0

ok, grazie ragazzi! – Larry

1

È possibile utilizzare i blocchi di inizializzazione:

class Foo { 
    //using static initializer block 
    static Map<String,String> m1 = new HashMap<String,String>(); 
    static { 
     m1.put("x","y"); 
     m1.put("a","b"); 
    }  

    //using initializer block 
    Map<String,String> m2 = new HashMap<String,String>(); 
    { 
     m2.put("x","y"); 
     m2.put("a","b"); 
    }  

} 
+0

Qualcuno ha puntato mi viene in mente una volta che usare inizializzatori di istanze invece di costruttori è una cattiva idea, in particolare perché rende più difficile la gestione delle eccezioni. inizializzatori statici vanno bene, però. –

+0

@Sergey: dipende. Leggi questo: http://stackoverflow.com/questions/1355810/how-is-an-instance-initializer-different-from-a-constructor –

+0

Non inserirei codice di errore negli inizializzatori, ma per operazioni sicure come riempire le collezioni non vedo problemi. – Landei

15

Se il Map sta per essere immutabili dopo la creazione e non vi dispiace l'aggiunta di una dipendenza, Guava offre un buon fluente syntax:

Map<K,V> aMap = ImmutableMap.<K,V>builder().put(key0, val0).put(key1,val1).build(); 

Se ti senti davvero esotico, la sintassi Scala ha esattamente la stessa cosa che desideri ed è interoperabile con altro codice Java:

val aMap = Map("a"->0, "b"->1) 

Si noti che il compilatore Scala sarà dedurre il tipo generico Map è String-Int, in base a ciò che si mette in esso, anche se è possibile specificare in modo esplicito come bene.

Tuttavia, se questo è solo un one-off, vorrei andare con la sintassi basata su inizializzatore. Sia la libreria Guava che la lingua di Scala hanno molto altro da raccomandare, ma imparare una nuova libreria/lingua potrebbe essere esagerato.

+0

+1 per il riferimento Scala :-) – Landei

0

Qualcosa di molto hacky..can essere migliorato, ma questo è solo una direzione: Definire un aiutante statica per convertire una matrice di oggetti a una mappa di questo tipo:

public static<K,V> Map<K, V> fromArray(Object[] anObjArray){ 
    int size = anObjArray.length; 
    Map<K, V> aMap = new HashMap<K, V>(); 
    for (int i=0;i<=size/2;i=i+2){ 
     K key = (K)anObjArray[i]; 
     V value = (V)anObjArray[i+1]; 
     aMap.put(key, value); 
    } 
    return aMap; 
} 

quindi è possibile creare una mappa utilizzare questo:

 Map<Integer, String> aMap = MapUtils.<Integer, String>fromArray(new Object[]{1, "one", 2,"two"}); 

io personalmente seconda Gauva costruttore suggerimento da @Carl però :-)

Problemi correlati