stream对多个字段分组_java8 stream 多字段分组、多个列汇总统计

AttendanceStatisticByDayDTO :

import lombok.Data;

import java.util.Date;

@Data

public class AttendanceStatisticByDayDTO {

/**

* 员工ID

*/

private String userId;

/**

* 员工编码

*/

private String userCode;

/**

* 员工名称

*/

private String userName;

/**

* 统计日期

*/

private Date statisticDate;

/**

* 应上时长

*/

private Float workDueHour;

/**

* 实上时长

*/

private Float workRealHour;

/**

* 统计次数

*/

private Integer statisticTimes;

/**

* 考勤配置ID

*/

private String attendanceTypeId;

/**

* 考勤配置名称

*/

private String attendanceTypeName;

}

ComputeGroupByDTO:

/**

* 用于统计的值

*/

@Data

public class ComputeGroupByDTO {

/**

* 总条数

*/

private long totalCount;

/**

* 总的工作小时数

*/

private Double dueHourSum;

/**

* 真实的小时数

*/

private Double realHourSum;

}

测试代码:

/**

* 分组的条件

*

* @param attendanceStatisticByDayDTO 考勤统计

* @return 返回分组的KEY

*/

private static AttendanceStatisticByDayDTO fetchGroupKey(final AttendanceStatisticByDayDTO attendanceStatisticByDayDTO) {

final AttendanceStatisticByDayDTO statisticByDay = new AttendanceStatisticByDayDTO();

statisticByDay.setUserId(attendanceStatisticByDayDTO.getUserId());

statisticByDay.setUserCode(attendanceStatisticByDayDTO.getUserCode());

statisticByDay.setUserName(attendanceStatisticByDayDTO.getUserName());

statisticByDay.setStatisticDate(attendanceStatisticByDayDTO.getStatisticDate());

statisticByDay.setAttendanceTypeId(attendanceStatisticByDayDTO.getAttendanceTypeId());

statisticByDay.setAttendanceTypeName(attendanceStatisticByDayDTO.getAttendanceTypeName());

return statisticByDay;

}

public static void main(final String[] args) {

final ListattendanceStatisticByDayDTOS = new ArrayList<>();

for (int i = 0; i < 100; i++) {

final AttendanceStatisticByDayDTO attendanceStatisticByDayDTO = new AttendanceStatisticByDayDTO();

attendanceStatisticByDayDTO.setUserId("" + (i % 5));

attendanceStatisticByDayDTO.setUserCode("" + (i % 5));

attendanceStatisticByDayDTO.setUserName("" + (i % 5));

attendanceStatisticByDayDTO.setWorkDueHour((float) (i % 5));

attendanceStatisticByDayDTO.setWorkRealHour((float) (i % 5));

attendanceStatisticByDayDTO.setStatisticTimes(i);

attendanceStatisticByDayDTO.setAttendanceTypeId("" + (i % 5));

attendanceStatisticByDayDTO.setAttendanceTypeName("" + (i % 5));

attendanceStatisticByDayDTOS.add(attendanceStatisticByDayDTO);

}

final MapgroupByMap = attendanceStatisticByDayDTOS.stream()

.collect(Collectors.groupingBy(n -> fetchGroupKey(n)

, Collectors.collectingAndThen(Collectors.toList(), m -> {

final long totalCount = m.stream().count();

final Double dueHourSum = m.stream()

.mapToDouble(AttendanceStatisticByDayDTO::getWorkDueHour).sum();

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("groupByMap=" + groupByMap.size());

groupByMap.forEach((k, v) -> {

System.out.println(JSON.toJSONString(k));

System.out.println(JSON.toJSONString(v));

});

}

响应结果:

groupByMap=5

{"attendanceTypeId":"4","attendanceTypeName":"4","userCode":"4","userId":"4","userName":"4"}

{"dueHourSum":80.0,"realHourSum":80.0,"totalCount":20}

{"attendanceTypeId":"0","attendanceTypeName":"0","userCode":"0","userId":"0","userName":"0"}

{"dueHourSum":0.0,"realHourSum":0.0,"totalCount":20}

{"attendanceTypeId":"3","attendanceTypeName":"3","userCode":"3","userId":"3","userName":"3"}

{"dueHourSum":60.0,"realHourSum":60.0,"totalCount":20}

{"attendanceTypeId":"1","attendanceTypeName":"1","userCode":"1","userId":"1","userName":"1"}

{"dueHourSum":20.0,"realHourSum":20.0,"totalCount":20}

{"attendanceTypeId":"2","attendanceTypeName":"2","userCode":"2","userId":"2","userName":"2"}

{"dueHourSum":40.0,"realHourSum":40.0,"totalCount":20}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用Java Stream的`collect()`方法结合`groupingBy()`和`summingInt()`来实现多个字段分组统计。 假设你有一个包含多个字段的对象表,你想要按照其中两个字段进行分组,并统计每个组中对象的数量。下面是一个示例代码: ```java import java.util.*; import java.util.stream.Collectors; class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } } public class Main { public static void main(String[] args) { List<Person> people = Arrays.asList( new Person("Alice", 25), new Person("Bob", 30), new Person("Alice", 35), new Person("Bob", 40), new Person("Charlie", 20) ); Map<String, Map<Integer, Long>> result = people.stream() .collect(Collectors.groupingBy(Person::getName, Collectors.groupingBy(Person::getAge, Collectors.counting()))); System.out.println(result); } } ``` 在上面的示例中,我们首先使用`groupingBy()`按照姓名字段对对象进行分组,然后在每个分组中再次使用`groupingBy()`按照年龄字段进行分组,并使用`counting()`统计每个分组中的对象数量。最后,将结果存储在一个嵌套的`Map`中。 输出结果将是一个类似于`{Alice={25=1, 35=1}, Bob={40=1, 30=1}, Charlie={20=1}}`的`Map`,其中外层的键是姓名,内层的键是年龄,值是对象数量。 你可以根据自己的需求修改代码来适应不同的字段统计方式。希望对你有帮助!如果还有其他问题,请随时问我。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值