如何基于ID识别List中重复Foo对象并合并其子集合(支持Stream)
用Java Stream高效合并重复Foo对象的方案
嘿,这个需求我之前做过类似的,完全可以用Stream来实现,而且效率还不错。核心思路就是按id分组聚合同ID的对象,再合并它们的子集合,具体来看:
一、高效识别重复对象的核心逻辑
要高效识别重复,最直接的方式就是利用哈希分组——把所有Foo对象按id作为key分到不同的组里,同一组的就是重复(同ID)的对象。Java的Collectors.groupingBy底层用的是HashMap,平均情况下分组操作的时间复杂度是O(n),非常高效,比手动遍历逐个比对要靠谱多了。
二、用Stream实现完整的合并逻辑
直接上代码,把mergeDuplicates和mergeChilds的实现都写清楚:
1. 完整代码示例
import java.util.*; import java.util.stream.Collectors; public class Foo { private String id; private Collection<String> childs; // 构造器与Getter方法,方便后续操作 public Foo(String id) { this.id = id; this.childs = new ArrayList<>(); } public Foo(String id, Collection<String> childs) { this.id = id; this.childs = new ArrayList<>(childs); } public String getId() { return id; } public Collection<String> getChilds() { return childs; } // 合并重复Foo的核心方法 private Collection<Foo> mergeDuplicates(Collection<Foo> fooList) { // 处理空输入,避免NPE if (fooList == null || fooList.isEmpty()) { return Collections.emptyList(); } return fooList.stream() // 按id分组,key为id,value为同id的Foo集合 .collect(Collectors.groupingBy(Foo::getId)) .entrySet() .stream() .map(entry -> { List<Foo> sameIdFoos = entry.getValue(); // 组内只有一个对象,直接返回 if (sameIdFoos.size() == 1) { return sameIdFoos.get(0); } // 从第一个对象开始,逐个合并后续对象 return sameIdFoos.stream() .reduce(this::mergeChilds) .orElseThrow(); }) .collect(Collectors.toList()); // 可替换为LinkedHashSet保持原顺序 } // 合并两个Foo的子集合 private Foo mergeChilds(Foo foo1, Foo foo2) { // 创建新对象避免修改原实例,若允许修改原对象可调整逻辑 Collection<String> mergedChilds = new ArrayList<>(foo1.getChilds()); // 若需要对子集合去重,可将ArrayList换成HashSet mergedChilds.addAll(foo2.getChilds()); return new Foo(foo1.getId(), mergedChilds); } }
2. 关键细节说明
- 分组操作:
Collectors.groupingBy(Foo::getId)一步完成重复对象的聚合,是识别重复的核心,简洁且高效。 - 合并逻辑:用
Stream.reduce替代手动循环,代码更简洁;分组后的集合不会为空,所以orElseThrow()是安全的。 - 子集合去重:如果要求合并后的
childs无重复字符串,只需把mergedChilds的实现换成HashSet,最后再转成你需要的集合类型即可。 - 空输入处理:开头的非空判断让代码更健壮,避免空指针异常。
三、效率说明
这个方案的时间复杂度是O(n)(n为输入Foo集合的大小):
- 分组操作是线性遍历,每个元素插入HashMap的平均时间为O(1);
- 子集合合并时,每个
child元素只会被遍历一次,整体仍保持线性复杂度。
相比手动嵌套遍历比对(O(n²)),这个方案在集合规模较大时效率提升非常明显。
内容的提问来源于stack exchange,提问作者T. Yoo
相关产品推荐
相关产品推荐

