Reputation: 421
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
Upvotes: 0
Views: 797
Reputation: 7165
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.
Upvotes: 1