【问题标题】:How to group values of map into lists based on key with java streams?如何使用 java 流根据键将映射值分组到列表中?
【发布时间】:2020-05-23 02:29:29
【问题描述】:

假设我有一个从Strings到一个从Strings到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}

我们可以完全丢弃外部地图的键。

使用 java.util 最好的方法是什么?我认为使用 Collectors.groupBy 方法可能有一些不错的方法,但我对此非常缺乏经验。

【问题讨论】:

  • 那么外层map的key就没有用了吗? (AB

标签: java hashmap java-stream flatmap


【解决方案1】:

我假设可能有两个以上的地图,所以让我们用它们制作一个列表:

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

然后我们可以在每个 Map 的 values() 上使用 flatMap,这为我们提供了 Map&lt;String, Integer&gt; 地图流。

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

有一个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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-06
    • 2016-05-21
    • 1970-01-01
    • 2023-03-15
    • 2013-05-04
    • 1970-01-01
    相关资源
    最近更新 更多