通过属性将地图的列表值转换为其平均值

时间:2016-09-13 12:45:10

标签: java lambda functional-programming java-8

我从Map<String,List<Rating>>开始。评分的方法为int getValue()

我希望最终得到Map<String,Integer>,其中整数值是按原始Rating.getValue()中的键分组的所有Map<String,List<Rating>>值的平均值。

我很高兴收到一些关于如何解决这个问题的想法。

2 个答案:

答案 0 :(得分:4)

可以使用IntStream方法对整数集合执行聚合操作。在您的情况下,average似乎是正确的使用方法(注意它返回Double,而不是Integer,这似乎是一个更好的选择。

您想要的是将原始地图的每个条目转换为新地图中的条目,其中密钥保持不变,并且值是List<Rating>元素的值的平均值。可以使用toMap Collector生成输出地图。

Map<String,Double> means =
    inputMap.entrySet()
            .stream()
            .collect(Collectors.toMap(Map.Entry::getKey,
                                      e->e.getValue()
                                          .stream()
                                          .mapToInt(Rating::getValue)
                                          .average()
                                          .orElse(0.0)));

答案 1 :(得分:4)

可以使用averagingInt作为下一步:

Map<String, Double> means =
    map.entrySet()
        .stream()
        .collect(
            Collectors.toMap(
                Map.Entry::getKey,
                e -> e.getValue().stream().collect(
                    Collectors.averagingInt(Rating::getValue)
                )
            )
        );

假设您希望更进一步,并且需要更多统计信息,例如countsumminmaxaverage,您可以考虑使用summarizingInt,然后获得IntSummaryStatistics而不是Double

Map<String, IntSummaryStatistics> stats =
    map.entrySet()
        .stream()
        .collect(
            Collectors.toMap(
                Map.Entry::getKey,
                e -> e.getValue().stream().collect(
                    Collectors.summarizingInt(Rating::getValue)
                )
            )
        );