Android 流媒体从地图上取平均值

Android streams average from a map

提问人:kkkkk 提问时间:8/9/2017 最后编辑:Manos Nikolaidiskkkkk 更新时间:8/10/2017 访问量:105

问:

我有一个对象列表

class Result {
    private String name;
    private Map<String, Double> map;

    // getters, constructor etc
}

我想按名称对其进行分组,并在映射中对每个键的双精度值进行平均。列表中的每个对象都具有具有相同键的映射。

我首先按名称分组

Map <String, List<Result>> grouppedByName = Stream.of(results)
        .collect(Collectors.groupingBy(Result::getName));

我不知道除了常规循环之外的下一步是什么。

示例数据:

INPUT:

name = "Name 1"
map:
KEY1, 10
KEY2, 1

name = "Name 1"
map:
KEY1, 20
KEY2, 7

name = "Name 2"
map:
KEY1, 2
KEY2, 3
--------------
OUTPUT:

name = "Name 1"
map:
KEY1, 15                           (10+20)/2 = 15
KEY2, 4                            (1+7)/2 = 4

name = "Name 2"
map:
KEY1, 2
KEY2, 3
Android 字典 lambda java-stream 平均值

评论

0赞 mac229 8/9/2017
你应该更具体,显示你的输入,并显示预期的输出
0赞 kkkkk 8/9/2017
我添加了一个示例数据

答:

1赞 Manos Nikolaidis 8/10/2017 #1

该方法将产生 .我们需要一种方法来将此映射的值转换为更有用的东西:groupingByMap<String, List<Result>>List<Result>

Map<String, Double> mapMerger(final List<Result> results) {
    return results.stream()
            .map(Result::getMap)
            .map(Map::entrySet)
            .flatMap(Set::stream)
            .collect(groupingBy(Entry::getKey, averagingDouble(Entry::getValue)));
}

这将从所有结果中的所有地图中提取所有类型的条目。它会将这些条目聚合到从每个键到该键所有值的平均值的映射中。Entry<String, Double>

我们可以通过从原始地图创建流来应用这种新方法(在您的问题中):grouppedByName

Map<String, Map<String, Double>> averagedByName = results.stream()
        .collect(groupingBy(Result::getName))
        .entrySet().stream()
        .collect(toMap(Entry::getKey, e -> mapMerger(e.getValue())));

如果你这样做,你应该得到:15

double avg = averagedByName.get("Name 1").get("KEY1");