Группировать в java 8 с несколькими уровнями группировки - PullRequest
2 голосов
/ 29 мая 2020

У меня такая структура

| 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 code Мне нужно сгруппировать этот ответ, чтобы не возвращать избыточные данные. Мои данные ответа выглядят как

@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;
            }));

Но как тогда мне заполнить список менеджерами и сотрудниками?

Ответы [ 2 ]

2 голосов
/ 29 мая 2020

@ Naman уже дал лучший ответ, просто хочу добавить, вы можете получить WorkersResponse таким же образом, используя collectingAndThen

List<WorkersResponse> requirement = workersList.stream()
        .collect(Collectors.collectingAndThen(Collectors.groupingBy(Workers::getDirectorName,
                Collectors.collectingAndThen(Collectors.groupingBy(Workers::getManagerName,
                        Collectors.mapping(w -> new Employee(w.getEmployeeName()),Collectors.toList())),
                    e -> e.entrySet().stream().map(ie -> new Manager(ie.getKey(), ie.getValue()))
                          .collect(Collectors.toList()))),
            e -> e.entrySet().stream().map(ie -> new WorkersResponse(ie.getKey(), ie.getValue()))
                          .collect(Collectors.toList())));
2 голосов
/ 29 мая 2020

Исходя из требований к группировке, вы должны попробовать использовать вложенную группировку вместе с 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());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...