多字段分组求和

50 阅读2分钟

摘要:

List<SubjectAmountVO> 集合按照借方科目和贷方科目进行分组,并计算借方金额且类型是BigDecimal和贷方金额 且类型是BigDecimal后返回List<SubjectAmountVO>集合还得包含借方科目名称和贷方科目名称。

解释:

  1. 分组逻辑: 使用 Collectors.groupingByBorrowerSubjectCodeLoanSubjectCode 进行分组。 使用 Collectors.collectingAndThen 计算每个分组的借方和贷方总金额,并确保结果类型为 BigDecimal。 在分组过程中,提取借方科目名称和贷方科目名称。
  2. 计算金额: 使用 reduce 方法对借方金额和贷方金额进行求和,并确保结果类型为 BigDecimal。
  3. 包含科目名称: 从分组列表中提取借方科目名称和贷方科目名称。
  4. 转换结果: 将分组结果转换为 List<SubjectAmountVO> 集合。 每个 SubjectAmountVO 对象包含借方科目代码、借方科目名称、贷方科目代码、贷方科目名称、借方总金额和贷方总金额。
  5. 排序: 按借方科目代码和贷方科目代码进行排序。
List<SubjectAmountVO> subjectAmountVOS = Arrays.asList(
    new SubjectAmountVO("A", "X", "借方科目A", "贷方科目X", new BigDecimal("100.00"), new BigDecimal("50.00")),
    new SubjectAmountVO("A", "X", "借方科目A", "贷方科目X", new BigDecimal("200.00"), new BigDecimal("100.00")),
    new SubjectAmountVO("B", "Y", "借方科目B", "贷方科目Y", new BigDecimal("300.00"), new BigDecimal("150.00"))
);
if (!CollectionUtils.isEmpty(subjectAmountVOS)) {
    // 按照借方科目和贷方科目分组,并计算借方金额和贷方金额
    Map<String, Map<String, SubjectAmountSummary>> groupedMap = subjectAmountVOS.stream()
            .collect(Collectors.groupingBy(
                    SubjectAmountVO::getBorrowerSubjectCode,
                    Collectors.groupingBy(
                            SubjectAmountVO::getLoanSubjectCode,
                            Collectors.collectingAndThen(
                                    Collectors.toList(),
                                    list -> {
                                        BigDecimal borrowerTotal = list.stream()
                                                .map(SubjectAmountVO::getBorrowerAmount)
                                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                                        BigDecimal loanTotal = list.stream()
                                                .map(SubjectAmountVO::getLoanAmount)
                                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                                        String borrowerSubjectName = list.get(0).getBorrowerSubjectName();
                                        String loanSubjectName = list.get(0).getLoanSubjectName();
                                        Integer sourcesDocuments = list.get(0).getSourcesDocuments();
                                        return new SubjectAmountSummary(borrowerTotal, loanTotal, borrowerSubjectName, loanSubjectName, sourcesDocuments);
                                    }
                            )
                    )
            ));

    // 转换为 List<SubjectAmountVO>
    List<SubjectAmountVO> result = new ArrayList<>();
    groupedMap.forEach((borrowerCode, loanMap) -> {
        loanMap.forEach((loanCode, summary) -> {
            SubjectAmountVO vo = new SubjectAmountVO();
            vo.setSourcesDocuments(summary.getSourceDocuments());
            vo.setBorrowerSubjectCode(borrowerCode);
            vo.setBorrowerSubjectName(summary.getBorrowerSubjectName());
            vo.setLoanSubjectCode(loanCode);
            vo.setLoanSubjectName(summary.getLoanSubjectName());
            vo.setBorrowerAmount(summary.getBorrowerTotal());
            vo.setLoanAmount(summary.getLoanTotal());
            result.add(vo);
        });
    });

    // 排序
    result.sort(Comparator
            .comparing(SubjectAmountVO::getBorrowerSubjectCode)
            .thenComparing(SubjectAmountVO::getLoanSubjectCode));
    return result;
}

分组后结果

List<SubjectAmountVO> result = Arrays.asList(
    new SubjectAmountVO("A", "X", "借方科目A", "贷方科目X", new BigDecimal("300.00"), new BigDecimal("150.00")),
    new SubjectAmountVO("B", "Y", "借方科目B", "贷方科目Y", new BigDecimal("300.00"), new BigDecimal("150.00"))
);