John Baum
John Baum

Reputation: 3331

Efficiently constructing related hierarchy of objects

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

Answers (1)

Daniel Rodriguez
Daniel Rodriguez

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

Related Questions