I have a StudentSchedule class that contains schedules of a student, the student may switch between rooms over time. There's no overlap with the date ranges so if a student stops at 2020-01-01 the next record would be 2020-01-02.
Given the StudentSchedule, I want a ProgramEnrollment which disregards room changes and coalesces contiguous StudentSchedules.
So given the following StudentSchedules
new StudentSchedule("A", "1", parse("2020-01-01"), parse("2020-01-02")), new StudentSchedule("B", "1", parse("2020-01-06"), parse("2020-01-10")), new StudentSchedule("B", "2", parse("2020-01-11"), null), new StudentSchedule("A", "2", parse("2020-01-03"), parse("2020-01-04"))
I want a result like
A 2020-01-01 - 2020-01-04 B 2020-01-06 - null
I have extracted the relevant code below. What I want to do is see if I can change the computeProgramEnrollments() to use more functions or streaming API including groupBy then flatmap then collect to a new list. Assuming it is possible.
import java.time.*; import java.util.*; import java.util.stream.*; import static java.time.LocalDate.*; class Main { public static void main(String[] args) { System.out.println(computeProgramEnrollments()); } static Stream<StudentSchedule> schedules() { return Stream.of( new StudentSchedule("A", "1", parse("2020-01-01"), parse("2020-01-02")), new StudentSchedule("B", "1", parse("2020-01-06"), parse("2020-01-10")), new StudentSchedule("B", "2", parse("2020-01-11"), null), new StudentSchedule("A", "2", parse("2020-01-03"), parse("2020-01-04")) ); } public static List<ProgramEnrollment> computeProgramEnrollments() { List<ProgramEnrollment> ret = new ArrayList<>(); String currentProgram = null; LocalDate currentStartDate = null; LocalDate currentStopDate = null; boolean newEnrollmentRequired = false; for (final StudentSchedule schedule : schedules().sorted(Comparator.comparing(StudentSchedule::getStartDate)).collect(Collectors.toList())) { if (Objects.equals(currentProgram, schedule.getProgram())) { if (currentStopDate != null && currentStopDate.plusDays(1).isEqual(schedule.getStartDate())) { // continuation currentStopDate = schedule.getStopDate(); } else { newEnrollmentRequired = true; } } else { newEnrollmentRequired = true; } if (newEnrollmentRequired) { if (currentProgram != null) { final ProgramEnrollment e = new ProgramEnrollment(currentProgram, currentStartDate, currentStopDate ); ret.add(e); } currentProgram = schedule.getProgram(); currentStartDate = schedule.getStartDate(); currentStopDate = schedule.getStopDate(); newEnrollmentRequired = false; } } if (currentProgram != null) { final ProgramEnrollment e = new ProgramEnrollment(currentProgram, currentStartDate, currentStopDate ); ret.add(e); } return ret; } } class StudentSchedule { String program; String room; LocalDate start; LocalDate stop; public StudentSchedule(String program, String room, LocalDate start, LocalDate stop) { this.program = program; this.room = room; this.start = start; this.stop = stop; } public String getProgram() { return program; } public String getRoom() { return room; } public LocalDate getStartDate() { return start; } public LocalDate getStopDate() { return stop; } } class ProgramEnrollment { String program; LocalDate start; LocalDate stop; public ProgramEnrollment(String program, LocalDate start, LocalDate stop) { this.program = program; this.start = start; this.stop = stop; } public String getProgram() { return program; } public LocalDate getStartDate() { return start; } public LocalDate getStopDate() { return stop; } public String toString() { return program + " " + start + "-" + stop + "\n"; } }