Может ли поток сбора операций быть конкретным POJO вместо карты? - PullRequest
1 голос
/ 08 мая 2019

Я хотел бы сгруппировать по нескольким полям и создать, и вывод, который является POJO.

Исходный POJO выглядит примерно так:

@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class DealDTO {
    @EqualsAndHashCode.Include
    private String id;

    private Float amount;
    private Date closeDate;
    private String stage;

    public int getYear() {
        return getLocalDate().getYear();
    }

    public int getMonth() {
        return getLocalDate().getMonthValue();
    }

    private LocalDate getLocalDate() {
        return getCloseDate().toInstant()
            .atZone(ZoneId.systemDefault()).toLocalDate();
    }
}

Целевой POJO

@Data
public class GroupByYearMonthStageDTO {
    private int year;
    private int month;
    private String stage;
    private DoubleSummaryStatistics statistics;
}

Код ниже производит ожидаемую группировку:

List<DealDTO> list;
var grouping = list.stream().collect(
  groupingBy(DealDTO::getYear,
    groupingBy(DealDTO::getMonth,
      groupingBy(DealDTO::getStage, summarizingDouble(DealDTO::getAmount)))));

Но ..... группировка имеет тип:

Map<Integer, Map<Integer, Map<String, DoubleSummaryStatistics>>> 

Я хотел бы посмотреть, есть лив операции сбора есть способ изменить выходные данные, чтобы иметь окончательный тип группировки:

List<GroupByYearMonthStageDTO>

Ответы [ 2 ]

1 голос
/ 08 мая 2019

В качестве первого параметра для groupingBy отправьте лямбду, которая создает ваш целевой POJO, а в качестве второго параметра используйте summarizingDouble сборщик. После этого вам придется пройти по приведенной карте и установить статистику

Map<GroupByYearMonthStageDTO, DoubleSummaryStatistics> collect = list.stream()
            .collect(groupingBy(d -> new GroupByYearMonthStageDTO(d.getYear(), d.getMonth(), d.getStage()),
                            summarizingDouble(DealDTO::getAmount)));

collect.forEach(GroupByYearMonthStageDTO::setStatistics);
Set<GroupByYearMonthStageDTO> groupByYearMonthStageDTOS = collect.keySet();
0 голосов
/ 08 мая 2019

Не зная, как выглядит Target POJO, я не могу реализовать эту для вас, но вам понадобится пользовательская реализация Collector. После того, как вы сделали свою группировку, вы можете передать сгруппированные данные в Collector, и это должно уменьшить их из сгруппированных данных в ваш POJO.

Обратите внимание, что может быть даже желательно пропустить группировку и вместо этого позволить вашему Collector справиться с этим.

Полезные ссылки:

Java Collector

* ** 1016 1017 * groupingBy ()

Группировка Java 8 с использованием пользовательского сборщика

...