Reputation: 3331
For this toy example, I have a list of Classrooms with id and name. I fetch these classrooms from a datasource and then, for each classroom, I will need students and teacher lists to be fetched. I then would like to create another object that takes in classroom.id, classroom.name and List<Student>, List<Teacher>
called Foo. The issue being Foo is an immutable object and must be instantiated when all info is available. Here is what I have tried:
List<Classroom> classrooms = dataSource.fetchClassroomsById(classroomIds);
Map<Integer, Classroom> idToClassroom = new HashMap<>();
classrooms.stream()
.forEach(classroom -> {idToClassroom.put(classroom.getId(), classroom);});
//get all students and teachers that belong to set of classroomIds passed in
List<Student> students = dataSource.fetchStudentsById(classroomIds);
List<Teacher> teachers = dataSource.fetchTeachersById(classroomIds);
for (Student student : students) {
//gets the classroom for which student belongs. This is where I get stuck.
idsToClassroom.get(student.getClassRoomId())
}
...
Basically, how can I construct my Foo object efficiently and compactly at this point?
Upvotes: 0
Views: 60
Reputation: 617
Use Collectors.groupingBy
to group students and teachers in lists of the same classroom id.
List<Classroom> classrooms = dataSource.fetchClassroomsById(classroomIds);
List<Student> students = dataSource.fetchStudentsById(classroomIds);
List<Teacher> teachers = dataSource.fetchTeachersById(classroomIds);
Map<Integer, List<Student>> classroomIdToStudent = students.stream()
.collect(Collectors.groupingBy(Student::getClassroomId));
Map<Integer, List<Teacher>> classroomIdToTeacher = teachers.stream()
.collect(Collectors.groupingBy(Teacher::getClassroomId));
List<Foo> foos = classrooms.stream().map(c -> new Foo(c.getId(), c.getName(),
classroomIdToStudent.get(c.getId()), classroomIdToTeacher.get(c.getId()))).collect(Collectors.toList());
Upvotes: 1