开发者

How to do map inversion with Guava with non-unique values?

H开发者_运维百科ow can we do that with Guava? Notice the presence of List<K> in the return type since many keys can map to the same value in any normal map.

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 seems to insist on the unicity of the values, but I don't have this luxury.


You can do this:

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

Do note that pretty much any time you write Map<K, List<V>> or Map<K, Set<V>> or some such, a ListMultimap<K, V> or SetMultimap<K, V> is what you really want.


Use a Multimap instead, pick one that uses a list, like ArrayListMultimap, that will allow dupes.

Also you don't have to write your own invert method, there's one provided in com.google.common.collect.Multimaps.


In case someone stumbles here now (well within Java's Stream era), here are two single-expression Stream-based solutions:

1) Immutable version based on ImmutableListMultimap + toImmutableListMultimap collector

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

2) Mutable version based on ArrayListMultimap + Multimaps.toMultimap collector

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜