Java8流:将值转换为列表的转置映射

Kha*_*lId 5 java java-8 java-stream

我有键映射为String,值为List.列表可以有10个唯一值.我需要将此映射转换为键为Integer,将值转换为List.示例如下:

输入:

"关键1":1,2,3,4

"Key-2":2,3,4,5

"Key-3":3,4,5,1

预期产量:

1:"Key-1","Key-3"

2:"Key-1","Key-2"

3:"Key-1","Key-2","Key-3"

4:"Key-1","Key-2","Key-3"

5:"Key-2","Key-3"

我知道使用for循环我可以实现这一点,但我需要知道这可以通过java8中的streams/lamda完成.

-谢谢.

Ale*_* C. 13

一个想法可能是从原始地图生成所有价值密钥对,然后按这些值对密钥进行分组:

import java.util.AbstractMap.SimpleEntry;

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toList;

...

Map<Integer, List<String>> transposeMap =
    map.entrySet()
       .stream()
       .flatMap(e -> e.getValue().stream().map(i -> new SimpleEntry<>(i, e.getKey())))
       .collect(groupingBy(Map.Entry::getKey, mapping(Map.Entry::getValue, toList())));
Run Code Online (Sandbox Code Playgroud)


sud*_*d29 2

这有点可怕(我通常尝试将其分解以使其更具可读性),但你可以这样做:

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

map.forEach((key, list) -> list.stream().forEach(
    elm -> transposeMap.put(elm,
        transposeMap.get(elm) == null ? Arrays.asList(key) : (Stream.concat(transposeMap.get(elm).stream(),
            Arrays.asList(key).stream()).collect(Collectors.toList())))));
Run Code Online (Sandbox Code Playgroud)

假设Map<String, List<Integer>> map您要转置的是您的原始地图。transposeMap将有您需要的转置地图。

  • @Jean-François Savard:使用这种更复杂的变体是没有意义的(除了测试之外),但这与“应该是[更简单的形式]”是不同的说法。 (2认同)