2017-08-09 33 views
1

平均我有对象的列表的Android流从地图

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 
+0

你应该更具体的,显示你的输入,并显示预期的输出 – mac229

+0

我添加了一个示例数据 – kkkkk

回答

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");