2010-09-09 2 views
12

Как мы можем это сделать с помощью Guava? Обратите внимание на наличие List<K> в возвращаемом типе, поскольку многие ключи могут сопоставляться с одним и тем же значением в любой нормальной карте.Как сделать преобразование карты с помощью Guava с уникальными значениями?

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 кажется настаивать на уникальности значений, но у меня нет такой роскоши.

ответ

27

Вы можете сделать это:

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

Обратите внимание, что в значительной степени в любое время вы пишете Map<K, List<V>> или Map<K, Set<V>> или некоторые таковой, ListMultimap<K, V> или SetMultimap<K, V> является то, что вы действительно хотите.

+0

Ницца, это было быстро. – lacroix1547

+1

Но это раздражает, чтобы быть вынужденным преобразовать в Multimap. И, учитывая усилие, которое они придают выступлениям, в будущем это может быть улучшено, с чем-то более сексуальным. – lacroix1547

+2

@ lacroix1547 А? 'Multimaps.forMap()' возвращает _view_ данной карты. Это почти не работает ... он просто вызывает конструктор и назначает карту полю. Вот и все. Рассмотрим адаптер, который позволяет использовать карту с такими методами, как 'invertFrom()', которые ожидают 'Multimap'. – ColinD

7

Используйте Multimap вместо этого, выберите тот, который использует список, например ArrayListMultimap, что позволит обманывать.

Также вам не нужно писать свой собственный метод инвертирования, он предоставляется в com.google.common.collect.Multimaps.

Смежные вопросы