You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 8实现Data列表转带累计求和的DataHistory列表并入库

用Java 8实现Data到DataHistory的累计转换

没问题,这就给你一步步拆解怎么实现这个需求——从包含多日多条记录的Data列表,生成带截至当日累计和的DataHistory列表,还能直接存入数据库用于表格展示。

思路梳理

核心步骤其实很清晰:

  • 先把原始Data按日期分组,计算出每天的int1和int2的当日总和
  • 对分组后的日期按时间顺序排序
  • 遍历排序后的日期,逐步累加计算截至当日的累计和,最终生成DataHistory对象

代码实现

首先,我们先调整一下类的定义(推荐用Java 8的LocalDate代替旧的Date类,更安全易用):

import java.time.LocalDate;

// 原始数据类
class Data {
    private LocalDate date;
    private int int1;
    private int int2;

    // 构造器、getter、setter省略,按需实现
    public Data(LocalDate date, int int1, int int2) {
        this.date = date;
        this.int1 = int1;
        this.int2 = int2;
    }

    public LocalDate getDate() { return date; }
    public int getInt1() { return int1; }
    public int getInt2() { return int2; }
}

// 历史累计数据类
class DataHistory {
    private LocalDate date;
    private int sumInt1BeforeOrEqualDate;
    private int sumInt2BeforeOrEqualDate;
    private String someOtherValues;

    // 构造器、getter、setter省略
    public DataHistory(LocalDate date, int sumInt1, int sumInt2, String someOtherValues) {
        this.date = date;
        this.sumInt1BeforeOrEqualDate = sumInt1;
        this.sumInt2BeforeOrEqualDate = sumInt2;
        this.someOtherValues = someOtherValues;
    }

    // toString方法方便调试
    @Override
    public String toString() {
        return "DataHistory{" +
                "date=" + date +
                ", sumInt1=" + sumInt1BeforeOrEqualDate +
                ", sumInt2=" + sumInt2BeforeOrEqualDate +
                '}';
    }
}

接下来是核心的转换逻辑,我们用Java 8的Stream API来实现:

import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class DataConverter {

    // 定义日期格式化器,匹配输入的dd/MM/yy格式
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yy");

    public static void main(String[] args) {
        // 模拟输入的原始Data列表
        List<Data> rawData = List.of(
                new Data(LocalDate.parse("01/01/18", DATE_FORMATTER), 2, 3),
                new Data(LocalDate.parse("01/01/18", DATE_FORMATTER), 0, 1),
                new Data(LocalDate.parse("02/01/18", DATE_FORMATTER), 0, 1),
                new Data(LocalDate.parse("02/01/18", DATE_FORMATTER), 3, 0),
                new Data(LocalDate.parse("03/01/18", DATE_FORMATTER), 1, 3)
        );

        // 1. 按日期分组,计算每日的int1和int2总和
        Map<LocalDate, DailySum> dailySumMap = rawData.stream()
                .collect(Collectors.groupingBy(
                        Data::getDate,
                        Collectors.collectingAndThen(
                                Collectors.toList(),
                                list -> new DailySum(
                                        list.stream().mapToInt(Data::getInt1).sum(),
                                        list.stream().mapToInt(Data::getInt2).sum()
                                )
                        )
                ));

        // 2. 将分组后的日期按升序排序
        List<Map.Entry<LocalDate, DailySum>> sortedDailyEntries = new ArrayList<>(dailySumMap.entrySet());
        sortedDailyEntries.sort(Comparator.comparing(Map.Entry::getKey));

        // 3. 计算累计和并生成DataHistory列表
        List<DataHistory> dataHistoryList = new ArrayList<>();
        int cumulativeInt1 = 0;
        int cumulativeInt2 = 0;

        for (Map.Entry<LocalDate, DailySum> entry : sortedDailyEntries) {
            LocalDate date = entry.getKey();
            DailySum dailySum = entry.getValue();

            cumulativeInt1 += dailySum.getInt1Sum();
            cumulativeInt2 += dailySum.getInt2Sum();

            // 这里的someOtherValues可以根据业务需求填充,比如固定值或其他计算结果
            dataHistoryList.add(new DataHistory(date, cumulativeInt1, cumulativeInt2, "自定义内容"));
        }

        // 打印结果验证
        dataHistoryList.forEach(System.out::println);
    }

    // 临时辅助类,存储每日的int1和int2总和
    private static class DailySum {
        private int int1Sum;
        private int int2Sum;

        public DailySum(int int1Sum, int int2Sum) {
            this.int1Sum = int1Sum;
            this.int2Sum = int2Sum;
        }

        public int getInt1Sum() { return int1Sum; }
        public int getInt2Sum() { return int2Sum; }
    }
}

代码解释

  1. 日期分组与每日求和:用Collectors.groupingBy按日期分组,再通过collectingAndThen把每组的Data列表转换成每日的总和对象DailySum,避免重复计算。
  2. 日期排序:把Map的entry转成列表后按日期升序排序,保证累计的顺序正确。
  3. 累计计算:用两个累加变量遍历排序后的每日数据,逐步累加得到截至当日的累计和,最后生成DataHistory对象。
  4. 日期解析:用DateTimeFormatter处理输入的dd/MM/yy格式字符串,转换成LocalDate对象。

运行结果

执行上述代码后,会输出:

DataHistory{date=2018-01-01, sumInt1=2, sumInt2=4}
DataHistory{date=2018-01-02, sumInt1=5, sumInt2=5}
DataHistory{date=2018-01-03, sumInt1=6, sumInt2=8}

完全符合需求:截至01/01的累计是2和4(2+0,3+1),截至02/01是5(2+3)和5(4+1),截至03/01是6(5+1)和8(5+3)。

如果需要兼容旧的Date类,只需要把LocalDate替换成Date,并调整日期解析的逻辑(比如用SimpleDateFormat)即可。

内容的提问来源于stack exchange,提问作者testeurFou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:41:27