【问题标题】:Can a stream collect opreation can be a specific POJO instead of a Map?流收集操作可以是特定的 POJO 而不是 Map 吗?
【发布时间】:2019-05-08 16:53:20
【问题描述】:

我想对多个字段进行分组并生成一个 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>

【问题讨论】:

  • 什么是DealDTO?在OriginalPojo 的列表中,您正在代码中对TargetPojo 的属性执行操作,这不太有意义。请进一步澄清问题。
  • DealDTO 是原始 POJO。它包含 groupingBy 操作中引用的所有方法。

标签: java java-8 java-stream


【解决方案1】:

groupingBy 的第一个参数发送创建目标 POJO 的 lambda,第二个参数使用 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();

【讨论】:

    【解决方案2】:

    在不知道Target POJO 看起来像什么的情况下,我无法真正您实现这个,但您需要的是自定义Collector 实现。完成分组后,您可以将分组数据传递给您的Collector,它必须将分组数据中的数据减少到您的 POJO 中。

    请注意,甚至可能需要跳过分组,而是让您的 Collector 处理它。

    有用的链接:

    Java Collector

    groupingBy()

    Java 8 grouping using custom collector

    【讨论】:

    • 感谢 cmets。我在原始帖子中包含 POJO 以使其更加清晰。实现一个自定义收集器,这就是我卡住的地方。找到的所有示例仅显示了一个分组级别。
    猜你喜欢
    • 2019-11-05
    • 1970-01-01
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-23
    • 2011-02-15
    • 1970-01-01
    相关资源
    最近更新 更多