How to apply sorting and limiting after groupby using Java streams

后端 未结 3 739
[愿得一人]
[愿得一人] 2021-01-15 19:30

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.

相关标签:
3条回答
  • 2021-01-15 20:04

    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())
    
    0 讨论(0)
  • 2021-01-15 20:06

    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())));
    
    0 讨论(0)
  • 2021-01-15 20:12

    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() ) ) ) );
    
    0 讨论(0)
提交回复
热议问题