As has been suggested, using a Map<String,List<Employee>> is probably what you want. I constructed a small class and an example to illustrate the process.
List<Employee> emps = List.of(
new Employee("001", "Jim"),
new Employee("002", "Bob"),
new Employee("001", "June"),
new Employee("002", "Jean"));
// For each employee, using departmentId as the key, construct
// a map containing lists of all employees that have that ID
Map<String, List<Employee>> empMap =
emps
.stream()
.collect(
Collectors.groupingBy(emp -> emp.departmentId)
);
for (Entry<?, ?> e : empMap.entrySet()) {
System.out.println(e.getKey() + "-->" + e.getValue());
}
class Employee {
public String departmentId;
public String name;
public Employee(String departmentId, String name) {
this.departmentId = departmentId;
this.name = name;
}
public String toString() {
return "(" + departmentId + " " + name + ")";
}
}
This displays
001-->[(001 Jim), (001 June)]
002-->[(002 Bob), (002 Jean)]
Another option, which would do the exact same thing is as follows:
This creates an empty map. Then it iterates over the list of employees and computes whether the value for the key exists. If it does, it returns the list and adds the entry to that list. If it doesn't, it then creates the new ArrayList and then adds the employee for that list, storing the list in the provided key.
Map<String, List<Employee>> emp2 = new HashMap<>();
for (Employee emp : emps) {
emp2.compute(emp.departmentId,
(ID, list) -> list == null ? new ArrayList<>()
: list).add(emp);
}
In this case my preference would be the first method.
Map<String,List<Employee>>?Map<String,Map<String,Employee>>?