如何按personId分组Candidate实体并聚合关联codeHswCandId?
按personId分组生成主条目并关联同组其他记录的实现方案
需求说明
按personId对Candidate列表分组,每组选取updateDate最近的记录作为主条目,保留其codeHswCandId,将同组内其他记录的codeHswCandId存入主条目的codeHswCandIdRelated列表。
实体与测试数据
实体定义:
@Getter @Setter @AllArgsConstructor @NoArgsConstructor @Builder @EqualsAndHashCode @ToString public class Candidate { private Integer personId; private String codeHswCandId; private List<String> codeHswCandIdRelated; private LocalDateTime updateDate; }
测试数据:
LocalDate today = LocalDate.of(2023,2,16); LocalTime now = LocalTime.now(); LocalDate yesterday = LocalDate.of(2023,2,15); LocalDate beforeYesterday = LocalDate.of(2023,2,14); List<Candidate> candidateList = List.of( Candidate.builder().personId(1).codeHswCandId("1").updateDate(LocalDateTime.of(today, now)).build(), Candidate.builder().personId(1).codeHswCandId("2").updateDate(LocalDateTime.of(yesterday, now)).build(), Candidate.builder().personId(1).codeHswCandId("3").updateDate(LocalDateTime.of(beforeYesterday, now)).build(), Candidate.builder().personId(2).codeHswCandId("4").updateDate(LocalDateTime.of(today, now)).build(), Candidate.builder().personId(2).codeHswCandId("5").updateDate(LocalDateTime.of(yesterday, now)).build(), Candidate.builder().personId(2).codeHswCandId("6").updateDate(LocalDateTime.of(beforeYesterday, now)).build() );
解决方案代码
利用Java Stream API完成分组和转换:
// 按personId分组 Map<Integer, List<Candidate>> groupedByPersonId = candidateList.stream() .collect(Collectors.groupingBy(Candidate::getPersonId)); // 处理每个分组生成目标列表 List<Candidate> output = groupedByPersonId.values().stream() .map(group -> { // 获取组内更新时间最新的主记录 Candidate mainCandidate = group.stream() .max(Comparator.comparing(Candidate::getUpdateDate)) .orElseThrow(() -> new IllegalArgumentException("分组内无候选记录")); // 收集同组其他记录的codeHswCandId List<String> relatedIds = group.stream() .filter(c -> !c.getCodeHswCandId().equals(mainCandidate.getCodeHswCandId())) .map(Candidate::getCodeHswCandId) .collect(Collectors.toList()); // 构建最终的Candidate对象 return Candidate.builder() .personId(mainCandidate.getPersonId()) .codeHswCandId(mainCandidate.getCodeHswCandId()) .codeHswCandIdRelated(relatedIds) .updateDate(mainCandidate.getUpdateDate()) // 可选,若不需要可省略 .build(); }) .collect(Collectors.toList());
代码说明
- 分组:通过
Collectors.groupingBy将原始列表按personId分组,得到每个用户对应的所有候选记录集合。 - 筛选主记录:对每个分组使用
max方法,以updateDate为比较依据,找出最新的记录作为主条目。 - 收集关联ID:过滤掉主记录后,提取剩余记录的
codeHswCandId组成关联列表。 - 构建结果:使用Builder模式复制主记录的核心字段,设置关联ID列表,生成最终的
Candidate对象。
特殊情况说明
如果同一personId下存在多条updateDate相同的最新记录,当前逻辑会选取其中一条作为主条目。若需要处理这种场景,可调整比较器(例如结合codeHswCandId排序)来确定主记录。
内容的提问来源于stack exchange,提问作者Dragg
相关产品推荐
相关产品推荐

