Java invert a map

2019-07-10 04:30发布

I need to invert an original map. which type is <Integer, String>, like {1 = A, 2 = A, 3 = B....}. I want to create a new map which is String to ArrayList because if 1 = A, and 2 = A, than I want to have something like this: A = [1, 2].

So how can I do that?

2条回答
相关推荐>>
2楼-- · 2019-07-10 04:57

You can try this:

HashMap<Integer, String> original = new HashMap<>();
HashMap<String, ArrayList<Integer>> inverted = new HashMap<>();

original.put(1, "A");
original.put(2, "B");
original.put(3, "C");
original.put(4, "A");

for (Integer key: original.keySet()) {
    String newKey = original.get(key);

    inverted.computeIfAbsent(newKey, k -> new ArrayList<>());
    inverted.get(newKey).add(key);

}
System.out.println(original);
System.out.println(inverted);

So, let's say HashMap<Integer, String> original is {1=A, 2=B, 3=C, 4=A}, then you will get {A=[1, 4], B=[2], C=[3]}.

EDIT: If you want a more generic version, as @Mr.Polywhirl has suggested, you can use:

public static final <T, U> Map<U, List<T>> invertMap(Map<T, U> map) {
    HashMap<U, List<T>> invertedMap = new HashMap<>();

    for (T key : map.keySet()) {
        U newKey = map.get(key);

        invertedMap.computeIfAbsent(newKey, k -> new ArrayList<>());
        invertedMap.get(newKey).add(key);

    }

    return invertedMap;
}
查看更多
不美不萌又怎样
3楼-- · 2019-07-10 05:00

You can easily do it using Java 8's stream API, below is an example:

public static void main(String[] args) throws FileNotFoundException {

    Map<Integer, String> map = new HashMap<>();
    map.put(1, "A");
    map.put(2, "A");
    map.put(3, "B");

    Map<String, List<Integer>> invertedMap = map.entrySet()
    .stream()
    .collect(Collectors.groupingBy(Entry::getValue, 
            Collectors.mapping(Entry::getKey, Collectors.toList())));

    System.out.println(invertedMap);

}
查看更多
登录 后发表回答