Java将数据按自然周分组

114 阅读1分钟

背景:

上周遇到一个需求,需要将查出来的报表数据按自然周分组。这个需求逻辑并不难,几个循环就可以解决,难的是怎么优雅地去实现。

1.编写一个日期分组实体类

@Data
public class DateGroupEntry<T> {

    private LocalDate startDate;  //自然周的第一天

    private LocalDate endDate;  //自然周的最后一天

    private List<T> data; //分组后的数据

    public boolean isInRange(LocalDate date) {
        if (date.isEqual(startDate) || date.isEqual(endDate)) {
            return true;
        }
        return startDate.isBefore(date) && endDate.isAfter(date);
    }

    /*
     * 将数据按日期分组
     */
    public void addData(List<User> dataList) {
        List<User> collect = dataList.stream().filter(user -> isInRange(user.getDate())).collect(Collectors.toList());
        this.data = (List<T>) collect;
    }

}

2.编写工具类

public class DateUtil {

    public static List<DateGroupEntry> weekGroup(LocalDate startDate, LocalDate endDate) {
        List<DateGroupEntry> dateEntries = new ArrayList<>();
        while (startDate.isBefore(endDate) || startDate.isEqual(endDate)) {
            DateGroupEntry dateEntry = new DateGroupEntry();
            LocalDate weekFirstDay = startDate.with(DayOfWeek.MONDAY); //获取自然周的第一天
            dateEntry.setStartDate(weekFirstDay);

            weekFirstDay = weekFirstDay.plusDays(7); //下一个自然周的第一天
            startDate = weekFirstDay;

            //自然周的第一天+6 = 自然周的最后一天
            dateEntry.setEndDate(dateEntry.getStartDate().plusDays(6)); //获取自然周的最后一天

            dateEntries.add(dateEntry);
        }
        return dateEntries;
    }

}

3.测试代码

public static void main(String[] args) {
    LocalDate startDate = LocalDate.of(2024, 10, 1);
    LocalDate endDate = LocalDate.of(2024, 10, 28);
    List<DateGroupEntry> dateEntries = weekGroup(startDate, endDate);
    List<User> users = new ArrayList<>();
    User user = new User();
    user.setDate(LocalDate.of(2024, 10, 1));
    user.setName("xyw");
    users.add(user);

    User user1 = new User();
    user1.setDate(LocalDate.of(2024, 10, 8));
    user1.setName("xiaoming");
    users.add(user1);

    User user2 = new User();
    user2.setDate(LocalDate.of(2024, 10, 9));
    user2.setName("ssss");
    users.add(user2);

    for (DateGroupEntry dateEntry : dateEntries) {
        dateEntry.addData(users);
        users.removeAll(dateEntry.getData());
    }
    System.out.println(dateEntries);

}

4.结果

image.png

总结

整体功能并不难,希望对有需要的人给予帮助!