2012-05-17 2 views
29

Se voglio creare un nuovo Multimap con semplici impostazioni predefinite, ho curently bisogno di fare qualcosa di simile:Modo compatto per creare Guava Multimaps?

private final Multimap<Key, Value> providersToClasses = Multimaps 
     .newListMultimap(
       new HashMap<Key, Collection<Value>>(), 
       new Supplier<List<Value>>() { 
        @Override 
        public List<Value> get() { 
         return Lists.newArrayList(); 
        } 
       }); 

perché Java non può dedurre il tipo corretto se Maps.newHashMap viene utilizzato per la mappa di backup. Naturalmente, questo può essere rifattorizzato in un metodo separato, ma esiste già un modo per scriverlo in modo più conciso?

risposta

49

Perché non stai utilizzando ArrayListMultimap.create() per un caso così semplice? È il modo predefinito per creare la semplice HashMap/ArrayList che è probabilmente la multimappa utilizzata più comunemente.

+2

Penso che tu intenda "ArrayListMultimap'.'HashMultimap' è per' HashMap'/'HashSet'. –

+0

Sì, intendevo ArrayListMultimap. Grazie per la modifica. –

+3

Perché stavo cercando nella classe sbagliata ('Multimaps') :) –

2

Per rispondere al problema dell'inferenza di tipo originale, è tuttavia possibile specificare i tipi generici su un metodo statico utilizzando Maps.<Key, Collection<Value>>newHashMap(), ma non è certamente più conciso di new HashMap<Key, Collection<Value>>() (potrebbe essere più coerente).

7

Mi imbatto in questo problema durante la scrittura di client e la creazione di mappe di parametri di query. Un bel modello succinta mi piace per la costruzione multimaps è quello di utilizzare ImmutableMultiMap#builder

Multimap<String, String> queryParams = 
    ImmutableMultimap.<String, String>builder() 
    .put("key-1", "value-1") 
    .put("key-1", "value-2") 
    .build(); 
3

In Java 8 questo è molto più bello, per tutti i tipi di multimaps. Questo per due ragioni:

Ecco come si presenta:

Multimap<Key, Value> providersToClasses = 
    Multimaps.newListMultimap(new HashMap<>(), ArrayList::new); 
4

Ecco soluzione compatta:

Multimap<Integer, String> multi = HashMultimap.create(); 
6

Le Guava documentation afferma che il metodo create sostenuta da alcune altre risposte "sarà presto deprecato" a favore delle diverse forme presentate di seguito, e dovrebbe quindi essere evitato.

Da Guava 21,0 in poi, il metodo consigliato di creare un oggetto Multimap in cui i valori vengono memorizzati in ArrayList collezioni è la seguente:

MultimapBuilder.hashKeys().arrayListValues().build(); 

È inoltre possibile utilizzare i parametri se si desidera specificare il numero previsto di chiavi nella vostra mappa e il numero atteso di valori per chiave:

MultimapBuilder.hashKeys(expectedKeys).arrayListValues(expectedValuesPerKey).build(); 

Infine, è possibile creare un nuovo Multimap da un esistere ing uno usando questo costrutto:

MultimapBuilder.hashKeys().arrayListValues().build(multimap); 

Se si desidera utilizzare le strutture di dati diversi da quelli ArrayLists nel vostro Multimap, è possibile sostituire la chiamata a arrayListValues() da una serie di altre, quotata here.