How to swap arrayMap values and keys in Java

前端 未结 4 669
孤独总比滥情好
孤独总比滥情好 2021-01-15 06:04

I\'m having a bit of trouble reversing a given map and storing its reversed keys and values into another map. I have a method prototype as follows:

public st         


        
相关标签:
4条回答
  • 2021-01-15 06:33

    I would first suggest writing a Graph class which abstracts away the underlying Map data structure. Of course, this just pushes the implementation to the Graph interface rather than dealing directly with the Map interface.

    So for now, stick with your map:

    Map<String, Set<String>> graph;
    Map<String, Set<String>> reverse;
    

    I suggest using Map.entrySet() to get the set of entries from your graph. Then for each Map.Entry, retrieve the key and value of each one. Next, for each "vertex" in the value Set, insert the key into the Set which is associated with the vertex.

    This might be more clear if I formatted it similar to Java code rather than English sentences. I hope you get the basic idea. Of course, using a pre-made and pre-tested solution would be preferrable if it fits into your constraints of project.

    0 讨论(0)
  • 2021-01-15 06:38

    Pseudocode, but close to real. Just use a Multimap.

    Multimap<String, String> ret = Multimaps.newSetMultimap();
    for (Entry<String, Set<String>> entry : graph) {
      for(String neighbor : entry.getValue()) {
        ret.addTo(neighbor, entry.getKey());
      }
    }
    
    0 讨论(0)
  • 2021-01-15 06:48

    You will need to loop over the entries in your map, and then, since the values are stored in a set, you will need to loop over that set. You will need to check your result map for each key and create a new set whenever a key does not yet exist.

    public static Map<String, Set<String>> reverse (Map <String, Set<String>> graph) {
        Map<String, Set<String>> result = new HashMap<String, Set<String>>();
        for (Map.Entry<String, Set<String>> graphEntry: graph.entrySet()) {
            for (String graphValue: graphEntry.getValue()) {
                Set<String> set = result.get(graphValue);
                if (set == null) {
                    set = new HashSet<String>();
                    result.put(graphValue, set);
                }
                set.add(graphEntry.getKey());
            }
        }
        return result;
    }
    
    0 讨论(0)
  • 2021-01-15 06:49

    Here's actual, working, up-to-date code using 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());
    

    (Disclosure: I contribute to Guava.)

    But if you can't use third-party libraries, do something like this...

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

    Or if you can use Java 8, use this...

    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())))
    
    0 讨论(0)
提交回复
热议问题