0

I want to create a Map of objects using multiple lists of different object types. I want to take an example so that it'd be more clear and easy to discuss.

class Employee {
Long id;
String name;
// getters, setters, and toString
}

class Department {
Long id;
String name;
// getters, setters, and toString
} 

class EmployeeDepartment {
Long id;
Long employeeId;
Long deptId;
// getters, setters, and toString
}

class Subject {
Long id;
String name;
// getters, setters, and toString
}

class EmployeeSubject {
Long id;
Long employeeId;
Long subjectId;
// getters, setters, and toString
}

Now, I have

List<Employee> emplList;
List<EmployeeDepartment> emplDeptList;
List<EmployeeSubject> emplSubList;

I want to get a Map by which I can make a search of employee using : deptId, and subjectId

Something like

Map<List<Long, Long>, List<Employee>> deptSubToEmpMap;
// representing Map<List<deptId, subId>, List<empl>>

// Or
Map<Long, Map<Long, List<Employee>> deptToSubToEmpMap;
// representing Map<deptId, Map<subId, List<empl>>

or any other convenient form if it's better than above representation.

Note: I'm a newbie to Java Streams

4
  • It is better to use your 2nd approach Commented Jul 6, 2020 at 11:53
  • But did you give it a try at least? It could have been Map<LookupRequest, List<Employee>> as well. Few of your classes are unrelated as they stand for now. Commented Jul 6, 2020 at 11:53
  • Hi Naman, all are of different class objects, not sure from where to start :| Commented Jul 6, 2020 at 11:57
  • All I could do was build Map<List<Long, Long>, List<EmployeeDepartment>> and Map<List<Long, Long>, List<EmployeeSubject>> seperately Commented Jul 6, 2020 at 12:04

1 Answer 1

1

You need to create EmployeeSubjectDepartment that will hold relation between employee, department and subject, as below,

@Getter@Setter
class EmployeeSubjectDepartment{
    Long empId;
    Long deptId;
    Long subId;

    public EmployeeSubjectDepartment(Long empId, Long deptId, Long subId) {
        this.empId = empId;
        this.deptId = deptId;
        this.subId = subId;
    }
}

And then merge emplDeptList and emplSubList to get emplyees

List<EmployeeSubjectDepartment> employeeSubjectDepartments = emplDeptList.stream()
                .flatMap(dept -> emplSubList.stream()
                        .filter(sub -> dept.employeeId.equals(sub.employeeId))
                        .map(sub -> new EmployeeSubjectDepartment(dept.employeeId, dept.deptId, sub.subjectId)))
                .collect(toList());

Map<Long, Map<Long, List<Long>>> result = employeeSubjectDepartments.stream()
        .collect(groupingBy(EmployeeSubjectDepartment::getDeptId,
                groupingBy(EmployeeSubjectDepartment::getSubId, mapping(e -> e.empId, toList()))));

This will result in Map with List of employeeIds.

If you want the List of employees, create EmployeeSubjectDepartment as below,

 class EmployeeSubjectDepartment{
        Employee emp;
        Long deptId;
        Long subId;
    } 

And then merge emplDeptList and emplSubList to get and map to emplyees from emplList

List<EmployeeSubjectDepartment> employeeSubjectDepartments = emplDeptList.stream()
                .flatMap(dept -> emplSubList.stream()
                        .filter(sub -> dept.employeeId.equals(sub.employeeId))
                        .map(sub -> new EmployeeSubjectDepartment(emplList.stream().filter(e -> e.id == sub.employeeId).findAny().orElse(null), dept.deptId, sub.subjectId)))
                .collect(toList());

Map<Long, Map<Long, List<Employee>>> result = employeeSubjectDepartments.stream()
        .collect(groupingBy(EmployeeSubjectDepartment::getDeptId,
                groupingBy(EmployeeSubjectDepartment::getSubId, mapping(e -> e.emp, toList()))));

This may not be a perfect solution but you can get the desired result.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.