import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

class Department {
	String deptId;

	public Department(String deptId) {
		this.deptId = deptId;
	}

	public String getDeptId() {
		return deptId;
	}

	@Override
	public String toString() {
		return "Department [deptId=" + deptId + "]";
	}
}

class Employee {
	String empId;
	List<Department> departments;

	public Employee(String empId, List<Department> departments) {
		this.empId = empId;
		this.departments = departments;
	}

	public String getEmpId() {
		return empId;
	}

	public List<Department> getDepartments() {
		return departments;
	}

	@Override
	public String toString() {
		return "Employee [empId=" + empId + ", departments=" + departments + "]";
	}
}

public class Main {
	public static void main(String[] args) {
		Department a = new Department("a");
		Department b = new Department("b");
		Department c = new Department("c");

		Employee e1 = new Employee("e1", List.of(a, b));
		Employee e2 = new Employee("e2", List.of(c, b));
		Employee e3 = new Employee("e3", List.of(c, a));
		Employee e4 = new Employee("e4", List.of(a, b, c));

		List<Employee> employees = List.of(e1, e2, e3, e4);
		Set<Department> departments = employees.stream().flatMap(employee -> employee.getDepartments().stream())
				.collect(Collectors.toSet());

		Map<Department, List<Employee>> map = 
				departments.stream()
							.collect(Collectors.toMap(
										Function.identity(),
										d -> employees.stream().filter(e -> e.getDepartments().contains(d)).collect(Collectors.toList())
									)
							);

		map.entrySet().forEach(System.out::println);
	}
}