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";
}
}