java 如何反转Map

whitzsjs  于 5个月前  发布在  Java
关注(0)|答案(2)|浏览(66)

让我们来看看Map:

  • A -> {1,2,3}
  • B -> {3,4,5}
  • C -> {2,3,5}

我需要反转这张Map并获得:

  • 1 -> {A}
  • 2 -> {A,C}
  • 3 -> {A,B,C}
  • 4 -> {B}
  • 5 -> {B,C}

我用这段代码实现了这一点:

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的方法?

6g8kf2rb

6g8kf2rb1#

如果您将HashMap<U, Set<V>>替换为HashMultimap<U, V>(它们是等价的,并且Multimap更易于使用),则现在可以使用Multimaps.invertFrom(),它将填充Multimap<V, U>
注意,正如Javadoc提到的,如果使用ImmutableMultimap,则可以直接调用ImmutableMultimap.inverse()

k2fxgqgv

k2fxgqgv2#

下面是一个使用流的解决方案:

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())));

字符串

分步分解

1.将Map转换为条目流

// Stream<Map.Entry<U, Set<V>>>
map.entrySet().stream()

1.将每个条目拆分为值列表

// Stream<Map.Entry<U, V>>
.flatMap(e -> e.getValue().stream().map(v -> Map.entry(e.getKey(), v)))

中的每个项目的单独项目
1.将这些条目分组到一个新的Map中,其中键等于以前的值,值包含Map到该值的每个原始键的列表。

// Map<V, Set<U>>
.collect(Collectors.groupingBy(
        Map.Entry::getValue,
        Collectors.mapping(Map.Entry::getKey, Collectors.toSet())));

相关问题