java - 使用 IntSummaryStatistics 跨多个字段求平均值
问题描述
我正在尝试使用 Java 8 流来创建单个 CarData 对象,该对象由来自列表中的所有 CarData 字段的平均值组成getCars
;
CarData = new CarData();
CarData.getBodyWeight returns Integer
CarData.getShellWeight returns Integer
List<CarData> carData = carResults.getCars();
IntSummaryStatistics averageBodyWeight = carData.stream()
.mapToInt((x) -> x.getBodyWeight())
.summaryStatistics();
averageBodyWeight.getAverage();
IntSummaryStatistics averageShellWeight = carData.stream()
.mapToInt((x) -> x.getShellWeight())
.summaryStatistics();
getShellWeight.getAverage();
我不想在我最终返回的结果中将这些重新组合在一起。
从视觉上看,这是我的清单
getCars() : [
{CarData: { getBodyWeight=10, getShellWeight=3 } }
{CarData: { getBodyWeight=6, getShellWeight=5 } }
{CarData: { getBodyWeight=8, getShellWeight=19 } }
]
我试图实现的输出是一个对象,它具有我指定的每个字段的平均值。不确定我是否需要使用Collectors.averagingInt
IntSummaryStatistics 或一些组合来实现这一点。对于这些技术中的任何一种,跨一个字段都很容易做到,只是不确定在使用多个整数字段时我缺少什么。
{CarData: { getBodyWeight=8, getShellWeight=9 } }
解决方案
从 JDK 12 开始,您可以使用以下解决方案:
CarData average = carData.stream().collect(Collectors.teeing(
Collectors.averagingInt(CarData::getBodyWeight),
Collectors.averagingInt(CarData::getShellWeight),
(avgBody, avgShell) -> new CarData(avgBody.intValue(), avgShell.intValue())));
对于较旧的 Java 版本,您可以这样做,将这个答案teeing
的实现添加到您的代码库并完全按照上面的方式使用它,或者创建一个为您的任务量身定制的自定义收集器,如Andreas 的答案所示。
或者考虑List
在内存中进行两次流式传输并不一定比在一个流中执行两个操作更糟糕,无论是可读性还是性能方面。
请注意,调用对象intValue()
的Double
行为与(int)
Andreas 回答中的强制转换相同。因此,无论哪种情况,如果要进行其他舍入行为,您都必须调整代码。
或者您考虑使用不同的结果对象,能够为平均值保存两个浮点值。
推荐阅读
- html - 如何设置
- 垂直?
- vb.net - 'GeckoButtonElement' 不包含带有 1 个参数的构造函数
- python - 熊猫:在多列上分组
- tensorflow - 使用 GradientTape 在 Tensorflow 中进行梯度计算 - 获得意外的无值
- laravel - Composer:SSL 证书问题:无法获取本地颁发者证书
- css - 用于在 React 中为自定义模态添加“弹出”效果的 CSS
- javascript - 如何将数据从 Flask 传递到 JavaScript
- javascript - Javascript DDT 不使用 csv 文件中的 $ 字符
- c# - 如何在 net core 3 中拥有一个具有前缀路由的基本控制器
- python - Python将两端带括号的列表转换为普通列表