提问人:kkkkk 提问时间:8/9/2017 最后编辑:Manos Nikolaidiskkkkk 更新时间:8/10/2017 访问量:105
Android 流媒体从地图上取平均值
Android streams average from a map
问:
我有一个对象列表
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
答:
1赞
Manos Nikolaidis
8/10/2017
#1
该方法将产生 .我们需要一种方法来将此映射的值转换为更有用的东西:groupingBy
Map<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");
评论