使用IntSummaryStatistics对多个字段求平均值 [英] Averaging across multiple fields with IntSummaryStatistics

查看:82
本文介绍了使用IntSummaryStatistics对多个字段求平均值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Java 8流创建单个CarData对象,该对象由列表中所有来自getCars的CarData字段的平均值组成;

I'm trying to use Java 8 streams to create a single CarData object, which consists of an average of all the CarData fields in the list coming from 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(); 

我不想在我最终返回的结果中将所有这些放回去.

I don't want to have to put each of these back together in my final returned result.

从视觉上看,这是我的列表

Visually, this is my list

getCars() : [
 {CarData: { getBodyWeight=10, getShellWeight=3 } }
 {CarData: { getBodyWeight=6, getShellWeight=5 } }
 {CarData: { getBodyWeight=8, getShellWeight=19 } }
]

,我要实现的输出是一个对象,该对象具有我指定的每个字段的平均值.不知道是否需要使用Collectors.averagingInt或IntSummaryStatistics的某种组合来实现此目的.对于这两种技术中的任何一种,都可以很容易地在一个字段中完成操作,只是不确定使用多个整数字段时我缺少什么.

and the output I'm trying to achieve is a single object that has the average of each of the fields I specify. not sure If I need to use Collectors.averagingInt or some combo of IntSummaryStatistics to achieve this. Easy to do across one field for either of these techniques, just not sure what I'm missing when using multiple integer fields.

 {CarData: { getBodyWeight=8, getShellWeight=9 } }

推荐答案

您需要编写自己的Collector,如下所示:

You need to write your own Collector, something like this:

class CarDataAverage {
    public static Collector<CarData, CarDataAverage, Optional<CarData>> get() {
        return Collector.of(CarDataAverage::new, CarDataAverage::add,
                            CarDataAverage::combine,CarDataAverage::finish);
    }
    private long sumBodyWeight;
    private long sumShellWeight;
    private int count;
    private void add(CarData carData) {
        this.sumBodyWeight += carData.getBodyWeight();
        this.sumShellWeight += carData.getShellWeight();
        this.count++;
    }
    private CarDataAverage combine(CarDataAverage that) {
        this.sumBodyWeight += that.sumBodyWeight;
        this.sumShellWeight += that.sumShellWeight;
        this.count += that.count;
        return this;
    }
    private Optional<CarData> finish() {
        if (this.count == 0)
            return Optional.empty();
        // adjust as needed if averages should be rounded
        return Optional.of(new CarData((int) (this.sumBodyWeight / this.count),
                                       (int) (this.sumShellWeight / this.count)));
    }
}

然后您可以像这样使用它:

You then use it like this:

List<CarData> list = ...

Optional<CarData> averageCarData = list.stream().collect(CarDataAverage.get());

这篇关于使用IntSummaryStatistics对多个字段求平均值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆