从Map <object,set <object >>转换为Map <string,set <string >>

时间:2018-09-18 11:06:33

标签: java java-8 java-stream

我有一张地图Map<String, Set<String>>

Map<String, Set<String> result = map.entrySet().parallelStream().collect(
            Collectors.groupingBy(Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toSet())));

我想将其转换为Map<String, Set<String>>。通过将值分组并交换键和值的位置。

但这行给了我

Type mismatch: cannot convert from Map<Object,Set<Object>> to Map<String,Set<String>>

3 个答案:

答案 0 :(得分:3)

您遇到的问题是您要创建的地图类型是:

Map<Set<String>, Set<String>>

不是Map<String, Set<String>>

因此,您需要首先扩展地图的值,例如:

Map<String, Set<String>> collect = map.entrySet()
    .parallelStream()
    // Expand (k, {v1, v2, v3}) to [(v1, k), (v2, k), (v3, k)]
    .flatMap(e -> e.getValue().stream().map(ee -> new SimpleEntry<>(ee, e.getKey())))
    .collect(
        Collectors.groupingBy(
            Map.Entry::getKey,
            Collectors.mapping(Map.Entry::getValue, Collectors.toSet())));

除非您真的需要并行处理,否则我认为使用循环会容易得多:

Map<String, Set<String>> collect = new HashSet<>();
for (Map.Entry<String, Set<String>> entry : map.entrySet()) {
  for (String v : entry.values()) {
      collect.computeIfAbsent(v -> new HashSet<>())
              .add(entry.getKey()));
  }
}

答案 1 :(得分:1)

这里是一个示例,考虑到您的初始Map是Object to Object。根据需要进行调整。

Map<Object,Object> map = new HashMap<>();
Map<String, Set<String>> result = map
            .entrySet()
            .parallelStream()
            .collect(Collectors.groupingBy(entry -> (String) entry.getKey(), 
                     Collectors.mapping(entry -> (String) entry.getKey(), Collectors.toSet())));

您的代码存在的问题是Map.Entry::getKey返回一个对象,而不是字符串。

答案 2 :(得分:1)

为避免混淆,我在回答我的问题。感谢@AndyTurner @alexrolea指出了解决方案。

Map<Set<String>, Set<String>> result = map.entrySet().parallelStream()
                .collect(
                Collectors.groupingBy(entry -> (Set<String>) entry.getValue(), 
                        Collectors.mapping(entry -> entry.getKey(), Collectors.toSet())));

我不得不将Map.Entry::getValue替换为entry -> (Set<String>) entry.getValue(),另一个也替换了。

这帮助我按值对地图进行分组并将其用作键。谢谢@nullpointer

实际上,这也有效。问题是我没有返回正确的数据类型。

Map<Set<String>, Set<String>> result = map.entrySet().parallelStream()
                .collect(
                Collectors.groupingBy(Map.Entry::getValue, 
                        Collectors.mapping(Map.Entry::getKey, Collectors.toSet())));