如何使按月获得平均数据更有效率

时间:2016-11-02 14:16:55

标签: java average

您好我有两个很长的代码块,我觉得可以提高效率,但我似乎无法想办法。

基本上,我有一份报告清单,我通过与记录日期相匹配的列表来获取某一年的所有报告。

接下来,我每月创建12个列表,按月分隔报告。

基本上我会在年度列表中逐步查看当年的每个报告并检查月份中的字符并将其分开,如下所示 -

for (int i = 0; i < yearlyReportList.size(); i++) {
        if (yearlyReportList.get(i).getDateTime().charAt(5) == '0' && yearlyReportList.get(i).getDateTime().charAt(6) == '1') {
            janReports.add(yearlyReportList.get(i));
        }
        if (yearlyReportList.get(i).getDateTime().charAt(5) == '0' && yearlyReportList.get(i).getDateTime().charAt(6) == '2') {
            febReports.add(yearlyReportList.get(i));
        }
        if (yearlyReportList.get(i).getDateTime().charAt(5) == '0' && yearlyReportList.get(i).getDateTime().charAt(6) == '3') {
            marchReports.add(yearlyReportList.get(i));
        }
....

接下来我平均每个月我需要的数据 - 我几乎复制并粘贴了12次,每次只更改它 -

if (janReports.size() == 0) {
        avgJanData = 0;
    } else {
        for (int i = 0; i < janReports.size(); i++) {
            janDataSum = janDataSum + janReports.get(i).getData();
        }

        avgJanData = janDataSum / janReports.size();
    }
....

但是这是一种更有效的方法,然后只需复制粘贴这段代码吧?

有人能举例说明如何使这段代码变得更好吗?

帮助表示赞赏。

2 个答案:

答案 0 :(得分:0)

您可以从代码段中提取方法:

public float average(Collection<Report> reports) {

    for (int i = 0; i < janReports.size(); i++) {
        janDataSum = janDataSum + janReports.get(i).getData();
    }


    return janDataSum / janReports.size();
}

然后你每个月都会调用这个方法。

如果您使用的是Java 8的其他解决方案:

 janRepors.stream().mapToDouble(o -> o.getData()).average(); // this will return the average as a double.

相同:每月调用一次。

关于代码的全局提示: 您还可以使用月份编号作为键来存储您的Reports而不是12变量,它应该简化您的代码。

答案 1 :(得分:0)

首先,我建议你摆脱丑陋的yearlyReportList.get(i).getDateTime().charAt(5) == '0' && yearlyReportList.get(i).getDateTime().charAt(6) == '1'

让我们在int中获得月号。

Integer.parseInt(yearlyReportList.get(i).getDateTime().substring(5, 6))

如果你告诉我们日期格式,我们可以做得更多&#34;自然&#34;方式(通过解析日期和提取月份)。

现在让我们解决您的copypast问题。

我建议制作数组并一次填写

int[] sumsByMonth = new int[12];
int[] countsByMonth = new int[12];
for(Report report: yearlyReportList) {
     int month = Integer.parseInt(r.getDateTime().substring(5, 6));
     sumsByMonth[month - 1] += r.getData();
     countsByMonth[month - 1]++;
}

默认情况下,数组填充0

现在你所要做的就是按计数划分总和

double[] averagesByMonth = new double[12];
for(int i = 0; i<12; i++) {
    averagesByMonth[i] = ((double)sumsByMonth[i])/countsByMonth[i];
}

转换为double,需要从整数除法转换为双除法。

<强>更新

你最好用它来提取月份:

        SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        Date date = format.parse(report.getDateTime());
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int month = calendar.get(Calendar.MONTH);

在这种情况下,您将获得基于月份数的0,并且在访问数组时无需减去1