retainAll实现交集(当前集合∩参数集合),removeAll实现差集(当前集合−参数集合);二者均直接修改原集合、返回是否发生改变的boolean值,不返回新集合。

Java 中的 retainAll 和 removeAll 是两个常用但容易被误解的集合操作方法,它们分别对应数学中“交集”和“差集”的语义,但实际行为严格依赖于调用对象(即被修改的集合)和参数集合的关系。正确理解它们的副作用与返回值,是安全进行布尔集合运算的关键。
retainAll 实现交集:保留当前集合中也存在于参数集合的元素
retainAll(Collection> c) 会**直接修改原集合**,只保留那些同时在 c 中存在的元素——这等价于求“当前集合 ∩ 参数集合”。注意:它不是返回新集合,也不保证参数集合不变。
- 调用后原集合变为交集结果,大小可能变小或不变(若已是子集)
- 若原集合为
ArrayList或HashSet,时间复杂度通常为 O(n),取决于c的contains效率 - 示例:
list1.retainAll(list2)后,list1变成list1 ∩ list2,list2不变
removeAll 实现差集:移除当前集合中所有在参数集合中出现的元素
removeAll(Collection> c) 会**从原集合中删除所有属于 c 的元素**,效果等同于“当前集合 − 参数集合”(即相对补集)。它不关心参数集合是否包含原集合没有的元素。
AI 舌诊面诊问诊医疗系统 + 诊疗商城系统源码是一套结合 AI 辅助诊断与商品转化的健康类程序,基于浩创云、ThinkPHP(PHP)开发,支持微信服务号与 H5 端,适合做中医舌诊面诊问答、健康建议推送以及配套诊疗商品的运营。
- 执行后原集合变为差集结果,即所有不在
c中的原元素 - 常见误用:想求
A − B却写成B.removeAll(A),结果是B被清空(因B中所有元素都不在A中时无变化;但若A包含B的部分元素,则B被删减——逻辑完全颠倒) - 正确写法:求
A − B,应调用A.removeAll(B)
注意不可变性与线程安全
这两个方法均要求集合可修改。对 Collections.unmodifiableXXX 包装的集合调用会抛出 UnsupportedOperationException。此外,它们都不是原子操作,多线程环境下需外部同步。
- 若需保留原始集合,务必先复制:
new ArrayList(original).retainAll(other) - 使用
Stream可实现无副作用的函数式写法,例如:original.stream().filter(other::contains).collect(Collectors.toSet()) - 对于大型集合,用
HashSet作参数能显著提升contains查找效率
返回值不是结果集合,而是操作是否发生改变
两个方法都返回 boolean:仅当原集合**实际被修改**(至少一个元素被保留或删除)时才返回 true。它不表示交集/差集是否为空,也不返回新集合引用。
- 即使交集为空,
retainAll清空原集合后仍返回true - 若原集合与参数无交集,
retainAll不改变原集合,返回false - 别用返回值判断结果大小——应检查集合 size() 或 isEmpty()

















