Java 8 lambda表达式用于查找列表中地图的平均值

7

如何使用Java-8流/lambda通过键找到列表映射的平均值?

示例:

List<Map<String, Double>> users = Arrays.asList(
  new HashMap<String, Double>()
    {{
      put("weight", 109.0);
      put("height", 180.2);          
     }},
  new HashMap<String, Double>()
    {{
      put("weight", 59.0);
      put("height", 186.2);          
     }}
 );

 Map<String, Double> statistics = 
 //<MISSED CODE with lambdas> (?)

 System.out.println(statistics);
 //{weight=84.0, height=183.1)

使用老式的foreach循环非常简单,我想知道是否可以用lambda表达式来实现。我需要这样做的原因是我将使用Apache Spark,而Java-8 lambda表达式将成为更标准的方法。


1
你是为了仅保留两个值而创建地图吗? - Andrew Tobilko
实际上,这不是一个地图,而是Scala库的Tuple4。目前有4个值,所以这不是即将发生的更改的情况。 - Bogdan
@Bogdan,既然你在使用Scala,为什么要寻求Java解决方案呢? - Flown
@AndrewTobilko 关于你删除的回答:它走在正确的轨道上,但必须保持运行总和和计数n的顺序,以便仅在最后进行除法。身份值为(0.0, 0.0, 0)。这也使并行合并成为可能。这就是DoubleSummaryStatistics的工作原理,尽管它更复杂,因为它使用补偿求和来提高准确性。 - Stuart Marks
@Flown:我正在使用一些Scala的库,而不是Scala本身。 - Bogdan
1个回答

6
Andrew Tobilko 所说,您应该使用适当的数据结构而不是Map
如果您坚持使用List<Map<>>,那么您需要使用Stream::flatMapMap::entrySet进行扁平化处理,并使用适当的Collector
List<Map<String, Double>> users = Arrays.asList(new HashMap<String, Double>() {
  {
    put("weight", 109.0);
    put("height", 180.2);
  }
}, new HashMap<String, Double>() {
  {
    put("weight", 59.0);
    put("height", 186.2);
  }
});

Map<String, Double> statistics = users.stream().flatMap(m -> m.entrySet().stream())
    .collect(
        Collectors.groupingBy(Entry::getKey, Collectors.averagingDouble(Entry::getValue))
    );

System.out.println(statistics);
// {weight=84.0, height=183.2}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接