首页 > 解决方案 > java 8中的Group By,具有多级分组

问题描述

我有这样的结构

| Director1 | Manager1 | Employee1 |
| Director1 | Manager1 | Employee2 |
| Director1 | Manager2 | Employee3 |
| Director2 | Manager3 | Employee4 |

我像这样从 Db 获取这些数据到 Pojo

@Data
public class Workers {
 private String directorName;
 private String managerName;
 private String employeeName;
}

DB 是非规范化的。

在java代码中我需要将此响应分组以不返回冗余数据。我的响应数据看起来像

@Data
public class WorkersResponse{
 private String directorName;
 ...
 private List<Manager> managers;
}

@Data
public class Manager{
 private String manager;
  ...
 private List<Employee> employee;
}

@Data
public class Employee{
 private String employee;
 ...
}

通过分组我想收到列表。现在我想出了如何对董事进行分组:

Map<WorkersResponse, List<Workers >> collect = all.stream()
            .collect(Collectors.groupingBy(v -> {
                WorkersResponse workersResponse= new WorkersResponse();
                workersResponse.setDirector(v.getDirectorName());
                return workersResponse;
            }));

但是我应该如何用经理和员工填充列表?

标签: javajava-streamgrouping

解决方案


根据分组要求,您应该尝试使用嵌套分组,Collectors.mapping例如:

Map<String, Map<String, List<String>>> groupingRequirement = workersList.stream()
        .collect(Collectors.groupingBy(Workers::getDirectorName,
                Collectors.groupingBy(Workers::getManagerName,
                        Collectors.mapping(Workers::getEmployeeName,
                                Collectors.toList()))));

此后,当您迭代收集的条目时,映射到所需类型的对象是唯一的约束Map-

List<WorkersResponse> workersResponses = groupingRequirement.entrySet().stream()
        .map(e -> new WorkersResponse(e.getKey(), // director name
                e.getValue().entrySet()
                        .stream()
                        .map(ie -> new Manager(ie.getKey(), // manager name
                                ie.getValue()
                                        .stream()
                                        .map(Employee::new)
                                        .collect(Collectors.toList())))
                        .collect(Collectors.toList())))
        .collect(Collectors.toList());

推荐阅读