google 网站打不开,用来做调查问卷的网站,外贸网站推广外包,注册360建筑网平台Java 值班排班算法 Demo#xff08;纯内存模拟#xff0c;无数据库#xff5c;真实节假日#xff09; 本示例基于 2025 年中国 1 月真实法定节假日安排 一、2025 年 1 月真实节假日说明#xff08;重要#xff09;
根据国务院公布的节假日安排#xff08;以示例简化纯内存模拟无数据库真实节假日本示例基于2025 年中国 1 月真实法定节假日安排一、2025 年 1 月真实节假日说明重要根据国务院公布的节假日安排以示例简化日期说明2025-01-01元旦休息2025-01-26周日补班2025-01-28 01-31春节休息⚠️ 注意01-31星期五虽然是工作日但因春节属于法定节假日应值班月底双人值班只能发生在“本来就需要值班的日期”二、模拟实体类不变1️⃣ RotaclassRota{LocalDatedate;ListStringusers;Stringweek;StringholidayType;// 0-普通 1-节假日 2-补班Stringremark;OverridepublicStringtoString(){returndate week - users [remark];}}2️⃣ HolidaysclassHolidays{LocalDatedate;Stringname;booleanoffDay;// true休息 false补班Holidays(LocalDatedate,Stringname,booleanoffDay){this.datedate;this.namename;this.offDayoffDay;}}三、修正后的核心排班方法关键修改点已标注publicstaticListRotabatchInsertRota(LocalDatestartDate,LocalDateendDate,ListStringemployees,booleantwoDutyAtMonthEnd,ListHolidaysholidaysList){SetLocalDateholidayDatesholidaysList.stream().filter(h-h.offDay).map(h-h.date).collect(Collectors.toSet());SetLocalDateweekendWorkDatesholidaysList.stream().filter(h-!h.offDay).map(h-h.date).collect(Collectors.toSet());MapString,LocalDatelastDutynewHashMap();employees.forEach(e-lastDuty.put(e,startDate.minusDays(1)));ListStringdutyQueuenewArrayList(employees);ListRotaresultnewArrayList();LocalDatecurrentstartDate;while(!current.isAfter(endDate)){LocalDatelastDayOfMonthcurrent.with(TemporalAdjusters.lastDayOfMonth());booleanisWeekendcurrent.getDayOfWeek()DayOfWeek.SATURDAY||current.getDayOfWeek()DayOfWeek.SUNDAY;booleanisHolidayholidayDates.contains(current);booleanisWeekendWorkweekendWorkDates.contains(current);// 是否“本来就需要值班”booleanneedDutyDay(isWeekend||isHoliday)!isWeekendWork;if(needDutyDay){ListStringdutyUsersnewArrayList();Stringuser1Collections.min(dutyQueue,Comparator.comparing(lastDuty::get));dutyQueue.remove(user1);lastDuty.put(user1,current);dutyUsers.add(user1);// 月底双人仅在“已是值班日”的前提下if(twoDutyAtMonthEndChronoUnit.DAYS.between(current,lastDayOfMonth)1!dutyQueue.isEmpty()){Stringuser2Collections.min(dutyQueue,Comparator.comparing(lastDuty::get));dutyQueue.remove(user2);lastDuty.put(user2,current);dutyUsers.add(user2);}RotarotanewRota();rota.datecurrent;rota.usersdutyUsers;rota.week星期一二三四五六日.charAt(current.getDayOfWeek().getValue()-1);if(isHoliday){rota.holidayType1;rota.remarkholidaysList.stream().filter(h-h.date.equals(current)).map(h-h.name).findFirst().orElse(节假日);}else{rota.holidayType0;rota.remark周末;}result.add(rota);dutyQueue.addAll(dutyUsers);}currentcurrent.plusDays(1);}returnresult;}四、Demo 主方法真实节假日数据publicstaticvoidmain(String[]args){LocalDatestartLocalDate.of(2025,1,1);LocalDateendLocalDate.of(2025,1,31);ListStringemployeesArrays.asList(张三,李四,王五,赵六);// 真实 2025 年 1 月节假日示例ListHolidaysholidaysArrays.asList(newHolidays(LocalDate.of(2025,1,1),元旦,true),newHolidays(LocalDate.of(2025,1,26),春节调休补班,false),newHolidays(LocalDate.of(2025,1,28),春节,true),newHolidays(LocalDate.of(2025,1,29),春节,true),newHolidays(LocalDate.of(2025,1,30),春节,true),newHolidays(LocalDate.of(2025,1,31),春节,true));ListRotarotaListbatchInsertRota(start,end,employees,true,holidays);rotaList.forEach(System.out::println);}五、最终正确 真实的控制台输出2025-01-01 星期三 - [张三] [元旦] 2025-01-04 星期六 - [李四] [周末] 2025-01-05 星期日 - [王五] [周末] 2025-01-11 星期六 - [赵六] [周末] 2025-01-12 星期日 - [张三] [周末] 2025-01-18 星期六 - [李四] [周末] 2025-01-19 星期日 - [王五] [周末] 2025-01-25 星期六 - [赵六] [周末] 2025-01-28 星期二 - [张三] [春节] 2025-01-29 星期三 - [李四] [春节] 2025-01-30 星期四 - [王五, 赵六] [春节] 2025-01-31 星期五 - [张三, 李四] [春节]