Invert Map with list value Map<Key, List<Value>> to Map <Value, Key> in Java 8

一世执手 提交于 2019-12-07 02:13:22

问题


I have a map kind of grouping values by key Map<String, List<Integer>>, i want to revert in order to map each value to the corresponding key

Example: I want to transform the code below

Map<String, List<Integer>> mapOfIntList = new HashMap<String, List<Integer>>();

mapOfIntList.put("UNIT", Arrays.asList(1, 2, 3, 8, 7, 0, 8, 6));
mapOfIntList.put("TEN", Arrays.asList(24, 90, 63, 87));
mapOfIntList.put("HUNDRED", Arrays.asList(645, 457, 306, 762));
mapOfIntList.put("THOUSAND", Arrays.asList(1234, 3456, 5340, 9876));

to another Map(Integer, String) where i can find : (1, "UNIT"), (2, "UNIT")...(24, "TEN"), (90, "TEN")...(645, "HUNDRED")...(3456, "THOUSAND")...


回答1:


You can use

Map<Integer, String> mapNumberToType = mapOfIntList.entrySet().stream()
    .collect(HashMap::new, (m,e)->e.getValue().forEach(v->m.put(v,e.getKey())), Map::putAll);

You may recognize the similarity to the forEach based code of this answer within the second function passed to collect (the accumulator) function. For a sequential execution, they do basically the same, but this Stream solution supports parallel processing. That’s why it needs the other two functions, to support creating local containers and to merge them.

See also the Mutable reduction section of the documentation.




回答2:


Or use two nested forEach

mapOfIntList.forEach((key, value) ->
            value.forEach(v -> {
                mapNumberToType.put(v, key);
            })
 );

as @nullpointer commented in one-liner

mapOfIntList.forEach((key, value) -> value.forEach(v -> mapNumberToType.put(v, key)));



回答3:


I have found a solution :

Map<Integer, String> mapNumberToType = mapOfIntList
    .entrySet()
    .stream()
    .flatMap(
            entry -> entry.getValue().stream()
                    .map(number -> Pair.of(number, entry.getKey()))
                    .collect(Collectors.toList()).stream())
    .collect(
            Collectors.toMap(Pair::getLeft,
                    Pair::getRight, (a, b) -> {
                        return a;
                    }));

System.out.println("Number/Type correspondance : " + mapNumberToType);

hope this helps anyone having the same problem !




回答4:


This would be simpler as:

 source.entrySet()
       .stream()
       .flatMap(e -> e.getValue().stream().map(s -> new AbstractMap.SimpleEntry<>(s, e.getKey())))
       .collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (l, r) -> l));


来源:https://stackoverflow.com/questions/54113664/invert-map-with-list-value-mapkey-listvalue-to-map-value-key-in-java-8

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!