Squ*_*gs. 2 java java-8 java-stream
我正在尝试使用 Java 8 流来创建一个 CarData 对象,该对象由列表中所有 CarData 字段的平均值组成getCars;
CarData = new CarData();
CarData.getBodyWeight returns Integer
CarData.getShellWeight returns Integer
Run Code Online (Sandbox Code Playgroud)
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();
Run Code Online (Sandbox Code Playgroud)
我不想在我最终返回的结果中把这些都放在一起。
视觉上,这是我的清单
getCars() : [
{CarData: { getBodyWeight=10, getShellWeight=3 } }
{CarData: { getBodyWeight=6, getShellWeight=5 } }
{CarData: { getBodyWeight=8, getShellWeight=19 } }
]
Run Code Online (Sandbox Code Playgroud)
我试图实现的输出是一个对象,它具有我指定的每个字段的平均值。不确定我是否需要使用Collectors.averagingInt或 IntSummaryStatistics 的一些组合来实现这一点。对于这些技术中的任何一种,在一个字段中都可以轻松完成,只是不确定在使用多个整数字段时我缺少什么。
{CarData: { getBodyWeight=8, getShellWeight=9 } }
Run Code Online (Sandbox Code Playgroud)
从 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())));
Run Code Online (Sandbox Code Playgroud)
对于较旧的 Java 版本,您可以执行以下任一操作:将这个答案的teeing实现添加到您的代码库中并完全按照上述方式使用它,或者创建一个为您的任务量身定制的自定义收集器,如Andreas 的答案所示。
或者考虑List在内存中流式传输两次不一定比在一个流中执行两个操作更糟糕,无论是可读性还是性能。
请注意,调用intValue()的Double对象具有相同的行为(int)在Andreas的答案转换。因此,无论哪种情况,如果需要其他舍入行为,您都必须调整代码。
或者您考虑使用不同的结果对象,能够为平均值保存两个浮点值。