如何在 Java 中交换 arrayMap 值和键

nit*_*ger 2 java map key-value

我在反转给定的映射并将其反转的键和值存储到另一个映射中时遇到了一些麻烦。我有一个方法原型如下:

public static Map<String, Set<String>> reverse (Map <String, Set<String>> graph);
Run Code Online (Sandbox Code Playgroud)

因此,如果我有有向图的示例键,则:

{c -> arraySet{f, e}}
{b -> d}
{a -> arraySet{c, b}} 
{d -> g}
{e -> d}
{f -> arraySet{g, d}}
Run Code Online (Sandbox Code Playgroud)

我需要有效地反转这个图,以便我有 d -> b 而不是 b -> d。

我认为这对我来说只是交换原始图中的值和键并将它们添加到 reverseMap 中。我想我可以遍历图中给定键的每组值,然后将它们存储在列表中。

不幸的是,我在实施和考虑它时遇到了麻烦。我真的很感激朝正确方向的推动。

Lou*_*man 5

这是使用Guava Multimaps的实际、有效、最新的代码:

SetMultimap<Integer, Integer> graph = HashMultimap.create();
graph.put(1, 2); // add an edge from 1 to 2
SetMultimap<Integer, Integer> inverse = Multimaps.invertFrom(
  graph, HashMultimap.<Integer, Integer> create());
Run Code Online (Sandbox Code Playgroud)

(披露:我为番石榴做出了贡献。)

但是,如果您不能使用第三方库,请执行以下操作...

Map<Integer, Set<Integer>> g;
Map<Integer, Set<Integer>> gInverse = new HashMap<Integer, Set<Integer>>();
for (Map.Entry<Integer, Set<Integer>> gAdj : g.entrySet()) {
  Integer v = gAdj.getKey();
  for (Integer w : gAdj.getValue()) {
    Set<Integer> wInverseAdj = gInverse.get(w);
    if (wInverseAdj == null) {
      gInverse.put(w, wInverseAdj = new HashSet<Integer>());
    }
    wInverseAdj.add(v);
  }
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您可以使用 Java 8,请使用此...

map.entrySet().stream()
   .flatMap(entryKToVs -> entryKToVs.getValue().stream()
       .map(v -> new AbstractMap.SimpleEntry<>(entryKToVs.getKey(), str)))
   .collect(groupingBy(Map.Entry::getValue, mapping(Map.Entry::getKey, toList())))
Run Code Online (Sandbox Code Playgroud)