I have the following list of Employee data which I need to group based on the employee department and then I want to find the 2 highest-paid employees in each department.
This part of code:
e -> e.stream().sorted().limit(limit).collect(Collectors.toList())
return List of List<Employee>
and not List<String>
, so either you change the type of the result to:
Map<String, List<Employee>> groupByTeachers =
// ...The rest of your code
Or if you expect Map<String, List<String>>
, change the collectingAndThen
to get the expected field, for example getName
or getDep
:
e -> e.stream().sorted().limit(limit)
.map(Employee::getDep) // for example getDep
.collect(Collectors.toList())
What you are looking for is to 1. group by department 2. then from the grouped entries, stream on the values, sort them based on an attribute and finally limit N values of it. This could be transformed into the code as:
Map<String, List<String>> highestPaidEmployeesGroupByDepartment = listOfEmp.stream()
.collect(Collectors.collectingAndThen(Collectors.groupingBy(Employee::getDept),
// part 2 starting here
m -> m.entrySet().stream()
.map(e -> Map.entry(e.getKey(), e.getValue().stream()
.sorted(Comparator.comparing(Employee::getSalary).reversed())
.limit(limit)
.map(Employee::getName)
.collect(Collectors.toList())))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))));
or an alternative without the collectingAndThen
would be
Map<String, List<String>> collect = listOfEmp.stream()
.collect(Collectors.groupingBy(Employee::getDept))
.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().stream()
.sorted(Comparator.comparing(Employee::getSalary).reversed())
.limit(limit)
.map(Employee::getName)
.collect(Collectors.toList())));
Here is the final answer for those who are interested.
Map<String, List<String>> groupByTeachers =
listOfEmp.stream()
.collect(
Collectors.groupingBy(
Employee::getDept,
Collectors.collectingAndThen(
Collectors.toList(),
e -> e.stream().sorted(Comparator.comparingLong(Employee::getSalary).reversed()).limit(limit).map(Employee::getName).collect(toList() ) ) ) );