当前位置: 代码网 > it编程>编程语言>Java > Java list实现多字段分组,多字段合并统计求和

Java list实现多字段分组,多字段合并统计求和

2025年10月26日 Java 我要评论
本文介绍了一种java中的list 进行多个字段分组,合并统计多个字段的聚合方法。实现比如员工id,员工部门等分组,并统计条数,工作时间等字段列
一 需求实例
分组的多个字段有:员工ID、员工编码、员工名称、考勤配置ID、考勤配置名称。
统计的多个字段有:总条数、总工作小时数、实际的小时数。

list 集合对象通过多个分组字段,统计多个字段,合并行,返回list集合。

二 代码实例

import lombok.Data;
import org.springframework.beans.BeanUtils;
 
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
 
/**
* @className: AttendanceStatisticByDayDTO
* @description: 包含 分组字段 和 统计字段
* @date: 2021/3/14
* @author: cakin
*/
@Data
class AttendanceStatisticByDayDTO {
    // 分组字段开始
    /**
     * 员工ID
     */
    private String userId;
    /**
     * 员工编码
     */
    private String userCode;
    /**
     * 员工名称
     */
    private String userName;
    /**
     * 考勤配置ID
     */
    private String attendanceTypeId;
    /**
     * 考勤配置名称
     */
    private String attendanceTypeName;
    // 分组字段结束
 
    // 统计字段开始
    /**
     * 应上时长
     */
    private Double workDueHour;
    /**
     * 实上时长
     */
    private Double workRealHour;
    /**
     * 统计次数
     */
    private Long statisticTimes;
    // 统计字段结束
}
 
/**
* @className: ComputeGroupByDTO
* @description: 统计字段
* @date: 2021/3/14
* @author: cakin
*/
@Data
class ComputeGroupByDTO {
    /**
     * 总条数
     */
    private Long totalCount;
 
    /**
     * 总的工作小时数
     */
    private Double dueHourSum;
 
    /**
     * 真实的小时数
     */
    private Double realHourSum;
}
 
/**
* @ClassName: GroupSumManyToMany
* @Description: 多字段分组,多字段求和  参考:https://blog.csdn.net/qq_38428623/article/details/103754446
* @Date: 2021/3/14
* @Author: cakin
*/
public class GroupSumManyToMany {
    /**
     * 功能描述:得到分组字段
     *
     * @param attendanceStatisticByDayDTO 考勤统计
     * @return 返回分组的KEY
     */
    private static AttendanceStatisticByDayDTO fetchGroupKey(final AttendanceStatisticByDayDTO attendanceStatisticByDayDTO) {
        final AttendanceStatisticByDayDTO statisticByDay = new AttendanceStatisticByDayDTO();
        statisticByDay.setUserId(attendanceStatisticByDayDTO.getUserId()); // 员工ID
        statisticByDay.setUserCode(attendanceStatisticByDayDTO.getUserCode()); // 员工编码
        statisticByDay.setUserName(attendanceStatisticByDayDTO.getUserName()); // 员工名称
        statisticByDay.setAttendanceTypeId(attendanceStatisticByDayDTO.getAttendanceTypeId()); // 考勤配置ID
        statisticByDay.setAttendanceTypeName(attendanceStatisticByDayDTO.getAttendanceTypeName()); // 考勤配置名称
        return statisticByDay;
    }
 
    /**
     * 功能描述:测试多字段分组,多字段求和
     *
     * @param args 命令行
     * @author cakin
     * @date 2021/3/14
     */
    public static void main(final String[] args) {
        final List<AttendanceStatisticByDayDTO> attendanceStatisticByDayDTOS = new ArrayList<>();
        // 初始化数据
        for (long i = 0; i < 100; i++) {
            final AttendanceStatisticByDayDTO attendanceStatisticByDayDTO = new AttendanceStatisticByDayDTO();
            attendanceStatisticByDayDTO.setUserId("" + (i % 5));
            attendanceStatisticByDayDTO.setUserCode("" + (i % 5));
            attendanceStatisticByDayDTO.setUserName("" + (i % 5));
            attendanceStatisticByDayDTO.setWorkDueHour((double) (i % 5));
            attendanceStatisticByDayDTO.setWorkRealHour((double) (i % 5));
            attendanceStatisticByDayDTO.setStatisticTimes(i);
            attendanceStatisticByDayDTO.setAttendanceTypeId("" + (i % 5));
            attendanceStatisticByDayDTO.setAttendanceTypeName("" + (i % 5));
            attendanceStatisticByDayDTOS.add(attendanceStatisticByDayDTO);
        }
 
        /**
         * 获取分组结果
         * 分组字段:员工ID、员工编码、员工名称、考勤配置ID、考勤配置名称,通过 fetchGroupKey 获取
         * 统计字段:通过 collectingAndThen 的第2个参数定义统计方式
         */
        final Map<AttendanceStatisticByDayDTO, ComputeGroupByDTO> groupByMap =
                attendanceStatisticByDayDTOS
                        .stream()
                        .collect(Collectors.groupingBy(n -> fetchGroupKey(n), Collectors.collectingAndThen(Collectors.toList(), m -> {
                            // totalCount 采用计数方式
                            final long totalCount = m.stream().count();
                            // dueHourSum 采用求和方式
                            final Double dueHourSum = m.stream().mapToDouble(AttendanceStatisticByDayDTO::getWorkDueHour).sum();
                            // realHourSum 采用求和方式
                            final Double realHourSum = m.stream().mapToDouble(AttendanceStatisticByDayDTO::getWorkDueHour).sum();
                            final ComputeGroupByDTO computeGroupBy = new ComputeGroupByDTO();
                            computeGroupBy.setTotalCount(totalCount); // 计数
                            computeGroupBy.setDueHourSum(dueHourSum); // 求和
                            computeGroupBy.setRealHourSum(realHourSum); // 求和
                            return computeGroupBy;
                        })));
        System.out.println("===============结果大小===============================");
        System.out.println("groupByMap=" + groupByMap.size());
 
        List<AttendanceStatisticByDayDTO> list = new ArrayList<>();
        System.out.println("===============中间结果===============================");
        groupByMap.forEach((k, v) -> {
            System.out.println(k);
            System.out.println(v);
            AttendanceStatisticByDayDTO attendanceStatisticByDayDTO = new AttendanceStatisticByDayDTO();
            BeanUtils.copyProperties(k, attendanceStatisticByDayDTO);
            attendanceStatisticByDayDTO.setStatisticTimes(v.getTotalCount());
            attendanceStatisticByDayDTO.setWorkDueHour(v.getDueHourSum());
            attendanceStatisticByDayDTO.setWorkRealHour(v.getRealHourSum());
            list.add(attendanceStatisticByDayDTO);
        });
 
        System.out.println("===============最终结果===============================");
        for (AttendanceStatisticByDayDTO attendanceStatisticByDayDTO : list) {
            System.out.println(attendanceStatisticByDayDTO);
        }
    }
}
三 代码测试结果
===============结果大小===============================
groupByMap=5
===============中间结果===============================
AttendanceStatisticByDayDTO(userId=2, userCode=2, userName=2, attendanceTypeId=2, attendanceTypeName=2, workDueHour=null, workRealHour=null, statisticTimes=null)
ComputeGroupByDTO(totalCount=20, dueHourSum=40.0, realHourSum=40.0)
AttendanceStatisticByDayDTO(userId=4, userCode=4, userName=4, attendanceTypeId=4, attendanceTypeName=4, workDueHour=null, workRealHour=null, statisticTimes=null)
ComputeGroupByDTO(totalCount=20, dueHourSum=80.0, realHourSum=80.0)
AttendanceStatisticByDayDTO(userId=0, userCode=0, userName=0, attendanceTypeId=0, attendanceTypeName=0, workDueHour=null, workRealHour=null, statisticTimes=null)
ComputeGroupByDTO(totalCount=20, dueHourSum=0.0, realHourSum=0.0)
AttendanceStatisticByDayDTO(userId=3, userCode=3, userName=3, attendanceTypeId=3, attendanceTypeName=3, workDueHour=null, workRealHour=null, statisticTimes=null)
ComputeGroupByDTO(totalCount=20, dueHourSum=60.0, realHourSum=60.0)
AttendanceStatisticByDayDTO(userId=1, userCode=1, userName=1, attendanceTypeId=1, attendanceTypeName=1, workDueHour=null, workRealHour=null, statisticTimes=null)
ComputeGroupByDTO(totalCount=20, dueHourSum=20.0, realHourSum=20.0)
===============最终结果===============================
AttendanceStatisticByDayDTO(userId=2, userCode=2, userName=2, attendanceTypeId=2, attendanceTypeName=2, workDueHour=40.0, workRealHour=40.0, statisticTimes=20)
AttendanceStatisticByDayDTO(userId=4, userCode=4, userName=4, attendanceTypeId=4, attendanceTypeName=4, workDueHour=80.0, workRealHour=80.0, statisticTimes=20)
AttendanceStatisticByDayDTO(userId=0, userCode=0, userName=0, attendanceTypeId=0, attendanceTypeName=0, workDueHour=0.0, workRealHour=0.0, statisticTimes=20)
AttendanceStatisticByDayDTO(userId=3, userCode=3, userName=3, attendanceTypeId=3, attendanceTypeName=3, workDueHour=60.0, workRealHour=60.0, statisticTimes=20)
AttendanceStatisticByDayDTO(userId=1, userCode=1, userName=1, attendanceTypeId=1, attendanceTypeName=1, workDueHour=20.0, workRealHour=20.0, statisticTimes=20)
(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com