Как сделать инверсию карты с гуавой с неуникальными значениями? - PullRequest
15 голосов
/ 09 сентября 2010

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

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

Ответы [ 3 ]

30 голосов
/ 09 сентября 2010

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

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> - это то, что вы действительно хотите.

7 голосов
/ 09 сентября 2010

Вместо этого используйте Multimap, выберите тот, который использует список, например, ArrayListMultimap , который разрешит дублированиепредоставляется в com.google.common.collect.Multimaps .

1 голос
/ 10 августа 2018

На тот случай, если кто-то споткнется здесь (в эпоху Java Stream), вот два решения на основе одного выражения Stream:

1) Неизменяемая версия на основе ImmutableListMultimap + toImmutableListMultimap коллектор

ImmutableListMultimap<V, K> output = inputMap.entrySet().stream()
        .collect(ImmutableListMultimap.toImmutableListMultimap(Map.Entry::getValue, Map.Entry::getKey));

2) Изменяемая версия на основе ArrayListMultimap + Multimaps.toMultimap коллектор

ListMultimap<V, K> output = inputMap.entrySet().stream()
        .collect(Multimaps.toMultimap(Map.Entry::getValue, Map.Entry::getKey, ArrayListMultimap::create));
...