如何使用Stream函数合并同名Tag对象的Occurrence集合
合并同名Tag的Occurrence集合(Java Stream实现)
假设你已经从JSON读取到了包含重复名称Tag的List<Tag>,可以通过Java Stream的分组+合并逻辑实现需求,以下是两种常用方案:
方案1:分组后展开合并(直观易读)
List<Tag> mergedTags = tags.stream() // 按Tag名称分组,同名Tag归入同一组 .collect(Collectors.groupingBy(Tag::getName)) .entrySet() .stream() .map(entry -> { String tagName = entry.getKey(); // 展开所有同组Tag的Occurrence并合并为一个集合 List<Occurrence> mergedOccurrences = entry.getValue().stream() .flatMap(tag -> tag.getOccurences().stream()) // 可选:如果需要去重或排序,可在此添加操作 // .distinct() // .sorted(Comparator.comparing(Occurrence::getTimestamp)) .collect(Collectors.toList()); // 创建合并后的新Tag对象 return new Tag(tagName, mergedOccurrences); }) .collect(Collectors.toList());
步骤说明:
- 分组:通过
Collectors.groupingBy(Tag::getName)将原始Tag列表转换为Map<String, List<Tag>>,key为Tag名称,value为对应名称的所有Tag实例。 - 合并Occurrence:遍历分组后的每个条目,用
flatMap将每个Tag的Occurrence集合展开为单一流,再收集为合并后的List。 - 生成合并Tag:用合并后的Occurrence集合和名称创建新的Tag对象,最终收集为结果列表。
方案2:分组时直接合并(更简洁)
如果Tag类支持修改或提供了合并逻辑,可以用Collectors.reducing作为下游收集器,在分组阶段完成合并:
List<Tag> mergedTags = tags.stream() .collect(Collectors.groupingBy( Tag::getName, Collectors.reducing(null, (tag1, tag2) -> { // 初始值为null时,创建新Tag(避免修改原对象) if (tag1 == null) { return new Tag(tag2.getName(), new ArrayList<>(tag2.getOccurences())); } // 将第二个Tag的Occurrence合并到第一个Tag中 tag1.getOccurences().addAll(tag2.getOccurences()); return tag1; }) )) .values() .stream() .collect(Collectors.toList());
注意事项:
- 确保Tag类的
getName()、getOccurences()方法可正常访问,且getOccurences()返回的集合支持添加操作(如ArrayList)。 - 如果需要避免修改原Tag对象,建议创建新的集合实例(如示例中的
new ArrayList<>(tag2.getOccurences())),防止原数据被意外修改。 - 若Occurrence存在重复数据,可在合并时添加
.distinct()(需为Occurrence重写equals()和hashCode()),或根据timestamp/number做自定义去重。
内容的提问来源于stack exchange,提问作者Rafael Piazza
相关产品推荐
相关产品推荐

