java - 如何使用java流根据键将map的值分组到列表中?

标签 java hashmap java-stream flatmap

假设我有从字符串到字符串到 int 的映射,例如

Map<String, Map<String, Integer>> myMap1 = new HashMap<>();
myMap1.put("A", Map.of("X", 1))
myMap1.put("B", Map.of("Y", 1))

Map<String, Map<String, Integer>> myMap2 = new HashMap<>();
myMap2.put("B", Map.of("Y", 3))

我想合并这些映射,以便我们得到一个映射,其中键是内部映射的键,值是相同键的内部映射值的平均值。 因此上面示例的输出将是

{"X" : 1, "Y", 2}

我们可以完全丢弃外部 map 的 key 。

使用 java.util.Date 实现此目的最好的方法是什么?我认为可能有一些很好的方法可以使用 Collectors.groupBy 方法来完成此操作,但我对此缺乏经验。

最佳答案

我假设可能有两个以上的 map ,所以让我们用它们创建一个列表:

    Collection<Map<String, Map<String, Integer>>> myMaps =
        List.of(myMap1, myMap2);

然后我们就可以在values()上使用flatMap了每个 Map 的数据流,为我们提供了 Map<String, Integer> 的流 map 。

我们可以获得entrySet()其中每个,然后将 flatMap 应用于这些条目集的流,为我们提供 Map.Entry<String, Integer> 的单个流对象,然后我们可以将其分组。

有一个groupingBy method which takes a second Collector通过收集所有看到的分组值来自定义组的值。我们可以使用 averaging collector 来获取平均值。 .

Map<String, Double> averages =
    myMaps.stream().flatMap(map -> map.values().stream())       // stream of Map<String, Integer>
        .flatMap(innerMap -> innerMap.entrySet().stream())      // stream of Map.Entry<String, Integer>
        .collect(Collectors.groupingBy(Map.Entry::getKey,       // group by String key
            Collectors.averagingInt(Map.Entry::getValue)));     // value for each key = average of its Integers

关于java - 如何使用java流根据键将map的值分组到列表中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60105208/

相关文章:

java - 如何使用另一个列表中的对象的属性创建一个新列表

java - 创建 2 个随机输入数字,然后询问解决方案以及用户是否想要添加另外 2 个数字

java - 如何使用compareTo按降序排列航类

java - 如何在java中切片或复制矩阵的中心部分

java - 迭代时 HashMap 抛出奇怪的异常

java - 如何在HashMap中创建和推送动态元素

java - 访问空组的流时,制作基于 Java 8 groupingBy 的映射 "null safe"

Java 8、流过滤器、反射、NoSuchMethodException

java - 分层死锁(具有依赖性),...或 : how do I get my "wait"s, "notify"s,设计对吗?

java - 适合 Java 的命令行解析和执行