Выполнение этого за один шаг, возможно, было бы возможно, но я думаю, что это не будет так читабельно! и делая это в несколько степпов, дайте понять ИМО!
на первом шаге: группировка по дате и статусу свойств.
Map<LocalDate, Set<Status>> groupByDateAndStatus = list.stream()
.collect(Collectors.groupingBy(Summary::getDate,
Collectors.mapping(Summary::getStatus, Collectors.toSet())));
{2020-01-27 = [ПРИНЯТЬ, ОТКАЗАНО], 2020-01-24 = [НЕУДАЧЕНО, ПРИНЯТО]]
во второй группе шагов резюме с дата и доступный статус .
Map<LocalDate, List<Summary>> map = list.stream()
.collect(Collectors.toMap(Summary::getDate,
summary -> new ArrayList<>(Collections.singletonList(summary)), YOURCLASS::merge));
и на последнем шаге добавьте summary
для отсутствующих status
.
EnumSet.allOf(Status.class)
.forEach(status -> groupByDateAndStatus.entrySet()
.stream()
.filter(entry -> !entry.getValue().contains(status))
.forEach(entry -> map.merge(entry.getKey(),
new ArrayList<Summary>(Collections.singletonList(new Summary(entry.getKey(), status, 0))),
YOURCLASS::merge)));
и метод слияния:
private static List<Summary> merge(List<Summary> l1, List<Summary> l2) {
l1.addAll(l2);
return l1;
}
вывод:
{
2020-01-27=[
Summary{date=2020-01-27, status=ACCEPTED, count=10},
Summary{date=2020-01-27, status=REJECTED, count=15},
Summary{date=2020-01-27, status=FAILED, count=0}],
2020-01-24=[
Summary{date=2020-01-24, status=ACCEPTED, count=1},
Summary{date=2020-01-24, status=FAILED, count=40},
Summary{date=2020-01-24, status=REJECTED, count=0}
]
}
Map<LocalDate, List<Summary>> map = new HashMap<>();
Map<LocalDate, Map<Status, Summary>> lookup = list.stream()
.collect(Collectors.groupingBy(Summary::getDate,
Collectors.toMap(Summary::getStatus, Function.identity())));
EnumSet.allOf(Status.class)
.forEach(status -> lookup
.forEach((key, value) ->
map.merge(key, new ArrayList<>(Collections.singletonList(value.getOrDefault(status, new Summary(key, status, 0)))),
YOURCLASS::merge)));