背景:
上周遇到一个需求,需要将查出来的报表数据按自然周分组。这个需求逻辑并不难,几个循环就可以解决,难的是怎么优雅地去实现。
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.结果
总结
整体功能并不难,希望对有需要的人给予帮助!