我想对多个字段进行分组,并产生和输出一个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>
答案 0 :(得分: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();
答案 1 :(得分:0)
在不知道Target POJO
是什么样的情况下,我真的无法为您实现 ,但是您需要的是自定义Collector
实现。完成分组后,可以将分组数据传递到Collector
,并且必须将其从分组数据中减少到POJO中。
请注意,甚至可能希望跳过分组,而由您的Collector
处理。
有用的链接: