我们来一张地图:
我需要反转这张地图并获得:
我成功地用这段代码做到了:
public static <U, V> Map<V, Set<U>> reverseMap(Map<U, Set<V>> map) {
Map<V, Set<U>> result = Maps.newHashMap();
for(Map.Entry<U, Set<V>> entry : map.entrySet()) {
for(V value : entry.getValue()) {
Set<U> set = result.get(value);
if(set == null) {
set = Sets.newHashSet();
result.put(value, set);
}
set.add(entry.getKey());
result.put(value, set);
}
}
return result;
}
但这只是反向索引,所以我认为可能存在一个预定义的方法来执行此操作。
有人知道这样的图书馆吗? Guava 中的方法?
如果您将
HashMap<U, Set<V>>
替换为 HashMultimap<U, V>
(它们是等效的,并且 Multimap
更易于使用),您现在可以使用 Multimaps.invertFrom()
,它将填充 Multimap<V, U>
。
ImmutableMultimap
,则可以直接调用 ImmutableMultimap.inverse()
。
这是 Java 8+ 中使用流的解决方案:
Map<V, Set<U>> invertedMap = map.entrySet().stream()
.flatMap(e -> e.getValue().stream()
.map(v -> Map.entry(e.getKey(), v)))
.collect(Collectors.groupingBy(
Map.Entry::getValue,
Collectors.mapping(Map.Entry::getKey, Collectors.toSet())));
// Stream<Map.Entry<U, Set<V>>>
map.entrySet().stream()
// Stream<Map.Entry<U, V>>
.flatMap(e -> e.getValue().stream().map(v -> Map.entry(e.getKey(), v)))
// Map<V, Set<U>>
.collect(Collectors.groupingBy(
Map.Entry::getValue,
Collectors.mapping(Map.Entry::getKey, Collectors.toSet())));