2010-09-09 2 views
12

Come possiamo farlo con Guava? Notare la presenza di List<K> nel tipo restituito poiché molte chiavi possono essere associate allo stesso valore in qualsiasi mappa normale.Come fare l'inversione della mappa con Guava con valori non univoci?

public static <K, V> Map<V, List<K>> inverse(Map<K, V> map){ 
    Map<V, List<K>> result = new LinkedHashMap<V, List<K>>(); 
    for (Map.Entry<K, V> entry : map.entrySet()) { 
     if(!result.containsKey(entry.getValue())){ 
      result.put(entry.getValue(), new ArrayList<K>());     
     } 
     result.get(entry.getValue()).add(entry.getKey()); 
    }   
    return result;   
} 

BiMap sembra insistere sulla unicità dei valori, ma non hanno questo lusso.

risposta

27

Si può fare questo:

Map<K, V> map = ...; 
ListMultimap<V, K> inverse = Multimaps.invertFrom(Multimaps.forMap(map), 
    ArrayListMultimap.<V,K>create()); 

fare notare che praticamente ogni volta che si scrive o Map<K, List<V>>Map<K, Set<V>> o qualcosa del genere, un ListMultimap<K, V> o SetMultimap<K, V> è ciò che si vuole veramente.

+0

Bello, è stato veloce. – lacroix1547

+1

Ma è fastidioso essere costretto a convertire in Multimap. E considerando lo sforzo che hanno messo sulle prestazioni, potrebbe essere migliorato in futuro, con qualcosa di più sexy. – lacroix1547

+2

@ lacroix1547 Eh? 'Multimaps.forMap()' restituisce _view_ della mappa data. Non fa quasi nessun lavoro ... chiama solo un costruttore e assegna la mappa a un campo. Questo è tutto. Consideralo un adattatore che ti permette di usare una mappa con metodi come 'invertFrom()' che si aspettano un 'Multimap'. – ColinD

7

Utilizzare invece una Multimap, selezionarne una che utilizzi un elenco, ad esempio , che consenta l'uso di duplicati.

Inoltre non è necessario scrivere il proprio metodo invert, ce n'è uno fornito in com.google.common.collect.Multimaps.