2012-05-22 12 views
15

ho provato la seguente linea:Come utilizzare i valori letterali di raccolta in Java 7?

Map<Character, Color> map={new Character('r'):Color.red,new Character('b'):Color.black}; 

Ma Netbeans 7 respinge questa, con il messaggio di errore '{' expected, ';' expected.

Ho impostato il formato sorgente/binario come "JDK 7" e la piattaforma su "JDK 1.7", c'è qualcos'altro che devo fare?

+0

I due punti in modo strano! :) –

+0

In Java 8, è possibile utilizzare questo trucco per ottenere letterali di carte ragionevoli con espressioni lambda: https://gist.github.com/galdosd/10823529 –

+2

Questo trucco dipende dal compilatore in uso. Penso che funzioni con Eclipse ma non con javac. –

risposta

44

Java 7 non supporta i valori letterali di raccolta. Essi sono previsti per Java 8. Non ce l'ha fatta anche in Java 8 come discusso in questa domanda: Are Project Coin's collection enhancements going to be in JDK8?

È possibile utilizzare la biblioteca di Google Guava se avete bisogno solo collezioni immutabili. ImmutableList, ImmutableSet e ImmutableMap hanno diversi metodi di fabbrica di overload o anche costruttori che rendono la creazione di collezioni facile:

List<Integer> list = ImmutableList.of(1, 1, 2, 3, 5, 8, 13, 21); 
Set<String> set = ImmutableSet.of("foo", "bar", "baz", "batman"); 
Map<Integer, String> map = ImmutableMap.of(1, "one", 2, "two", 3, "three"); 

EDIT

Java 9 sarà probabilmente aggiungere collection factory methods simili a quelle di Guava:

List.of(a, b, c); 
Set.of(d, e, f, g); 
Map.of(k1, v1, k2, v2) 

Map.ofEntries(
    entry(k1, v1), 
    entry(k2, v2), 
    entry(k3, v3), 
    // ... 
    entry(kn, vn) 
); 
+1

Oh, avrei dovuto cercarlo. È un peccato, davvero; Non vedevo l'ora di utilizzare i letterali di raccolta. Grazie! – DaedalusUsedPerl

10

È necessario definire un'implementazione cartografica concreta, eventualmente combinata con l'inizializzazione doppia coppia:

Map<Character, Color> map = new HashMap<Character, Color>() {{ 
    put(new Character('r'), Color.red); 
    put(new Character('b'), Color.black); 
}}; 
+1

Hmm, se qualcuno valuta un post, sarebbe bello avere qualche feedback sul perché. Siamo tutti qui per imparare, no? – Thomas

+7

Personalmente non ho votato, ma vedo due problemi con il tuo codice. Innanzitutto, creare una sottoclasse anonima solo per l'inizializzazione non è una buona pratica. Vedi http://stackoverflow.com/a/924536/581205 In secondo luogo, non devi creare manualmente una nuova istanza di Carattere, la funzione di autoboxing lo fa per te: 'put ('r', Color.red);' – Natix

+7

@ Natix sì, l'inizializzazione con doppia parentesi non è veramente raccomandata, l'ho appena menzionata come risposta alla domanda dell'OP. È vero che ci sono alternative molto migliori per riuscirci. Oltre a ciò, la creazione manuale di un 'carattere' (boxing manuale) o l'uso di autoboxing non è in realtà un motivo per un downrate. È una questione di stile e ho cercato di utilizzare il più possibile il codice dell'OP per mantenere bassa la confusione. – Thomas

0

Per espandere un po 'sul risposta di Thomas ... Mappa è un'interfaccia, e deve essere istanziato attraverso una delle implementazioni concrete associate (HashMap, TreeMap o LinkedHashMap). È ancora una buona pratica; tuttavia, dichiarare la variabile di riferimento come implementazione dell'interfaccia anziché come concreto specifico, in quanto fornisce flessibilità futura.

Per quanto riguarda lo snippet di codice, penso che siano comunque necessarie le coppie valore-chiave definite nel lato assegnazione della dichiarazione. Quindi, vorrei cambiare:

Map<Character, Color> map = new HashMap<>() {{ 

a

Map<Character, Color> map = new HashMap<Character, Color>() {{ 
+4

No, l'operatore <> è stato aggiunto in Java 1.7 come zucchero sintattico, quindi non è necessario essere così dettagliato. – lmsurprenant

+3

@lmsurprenant non è possibile utilizzare <> con classi interne anonime –

Problemi correlati