Java中求集合差集核心用removeAll():A.removeAll(B)得A−B,需复制可修改集合;自定义对象须重写equals/hashCode;对称差集需组合计算;Stream方式适合只读场景。

Java 中找出两个集合的差集,核心是用 removeAll() 方法:它会从调用方集合中移除所有存在于参数集合中的元素,结果即为“调用方对参数方的差集”(A − B)。
基本差集:A 减去 B
这是最常用场景:保留集合 A 中有、但集合 B 中没有的元素。
- 必须确保调用方集合是可修改的(如
new ArrayList(a)或new HashSet(a)),因为removeAll()会直接修改原集合 -
removeAll()返回boolean,表示是否发生了变化,实际差集就是调用后剩下的元素 - 原始集合 A 不应被直接复用(若需保留),建议先复制一份再操作
示例:
ListList
List
diff.removeAll(b); // 移除 b 中所有元素
System.out.println(diff); // [apple, cherry]
注意元素类型必须正确重写 equals 和 hashCode
如果集合里是自定义对象(比如 User 类),removeAll() 能否正确识别“相同元素”,完全取决于该类是否重写了 equals() 和 hashCode()。
立即学习“Java免费学习笔记(深入)”;
- 没重写时,默认按引用比较,两个内容相同的对象也会被视为不同,导致差集计算错误
- 例如两个
new User("Alice", 25)实例,若未重写equals,removeAll不会把它们当作同一个元素移除 - 推荐用 Lombok 的
@EqualsAndHashCode,或 IDE 自动生成这两个方法
对称差集(A Δ B):只在其中一个集合中出现的元素
对称差集 = (A − B) ∪ (B − A),即“互斥部分”。Java 没有内置方法,但可以组合实现:
- 先复制 A,执行
removeAll(B)得到 A−B - 再复制 B,执行
removeAll(A)得到 B−A - 最后合并两个结果(用
addAll())
示例(用 Set 更合适,避免重复):
SetSet
Set
symDiff.removeAll(b);
symDiff.addAll(new HashSet(b) {{ removeAll(a); }});
System.out.println(symDiff); // [a, d]
Stream 方式(Java 8+,适合只读场景)
如果不想修改原集合,且偏好函数式风格,可用 Stream 过滤:
a.stream().filter(x -> !b.contains(x)).collect(Collectors.toList())- 注意:当
b是大集合时,contains()效率依赖其底层实现;建议b是HashSet(O(1) 查找),而非ArrayList(O(n)) - 此方式不改变任何集合,语义清晰,适合链式处理或临时计算
基本上就这些。差集运算本身不复杂,但容易忽略可变性、对象相等性、性能这三点。










