Java中如何按GroupNum聚合实体并合并日期范围
按GroupNum聚合Entity对象的实现方案
首先定义基础实体类和结果类(示例):
// 原Entity类 public class Entity { private String groupNum; private LocalDate start; private LocalDate stop; // 构造器、getter、setter自行补充 } // 聚合结果类 public class MergeResult { private String groupNum; private LocalDate firstStart; private LocalDate lastStop; public MergeResult(String groupNum, LocalDate firstStart, LocalDate lastStop) { this.groupNum = groupNum; this.firstStart = firstStart; this.lastStop = lastStop; } // getter、toString自行补充 }
方法一:Java 8+ Stream API 实现
利用Collectors.groupingBy分组后,直接提取每组首尾元素的日期(若原列表同组元素已按时间顺序排列):
List<Entity> entityList = new ArrayList<>(); // 假设已完成entityList的数据填充 List<MergeResult> mergedResults = entityList.stream() // 按groupNum分组 .collect(Collectors.groupingBy(Entity::getGroupNum)) .entrySet().stream() .map(entry -> { List<Entity> group = entry.getValue(); // 若同组元素未按时间排序,需先执行排序: // group.sort(Comparator.comparing(Entity::getStart)); LocalDate firstStart = group.get(0).getStart(); LocalDate lastStop = group.get(group.size() - 1).getStop(); return new MergeResult(entry.getKey(), firstStart, lastStop); }) .collect(Collectors.toList());
如果不需要依赖列表顺序,而是要提取最早的Start日期和最晚的Stop日期,可以改用最值查找:
List<MergeResult> mergedResults = entityList.stream() .collect(Collectors.groupingBy(Entity::getGroupNum)) .entrySet().stream() .map(entry -> { List<Entity> group = entry.getValue(); LocalDate earliestStart = group.stream() .map(Entity::getStart) .min(LocalDate::compareTo) .orElse(null); LocalDate latestStop = group.stream() .map(Entity::getStop) .max(LocalDate::compareTo) .orElse(null); return new MergeResult(entry.getKey(), earliestStart, latestStop); }) .collect(Collectors.toList());
方法二:传统遍历 + HashMap 实现
兼容Java 8之前的版本,逻辑更直观:
List<Entity> entityList = new ArrayList<>(); // 假设已完成entityList的数据填充 // 第一步:按groupNum分组 Map<String, List<Entity>> groupMap = new HashMap<>(); for (Entity entity : entityList) { String groupNum = entity.getGroupNum(); // 不存在则创建新列表,再添加元素 groupMap.computeIfAbsent(groupNum, k -> new ArrayList<>()).add(entity); } // 第二步:生成聚合结果 List<MergeResult> mergedResults = new ArrayList<>(); for (Map.Entry<String, List<Entity>> entry : groupMap.entrySet()) { List<Entity> group = entry.getValue(); // 按需排序:group.sort(Comparator.comparing(Entity::getStart)); LocalDate firstStart = group.get(0).getStart(); LocalDate lastStop = group.get(group.size() - 1).getStop(); mergedResults.add(new MergeResult(entry.getKey(), firstStart, lastStop)); }
内容的提问来源于stack exchange,提问作者Rody
相关产品推荐
相关产品推荐

