Java 8起推荐用removeIf()批量删除,语义清晰、线程安全、性能好;复杂逻辑或低版本JDK可用Stream筛选后removeAll;避免增强for或正向for直接remove导致异常或漏删。

直接用 removeIf() 最省心
Java 8 起原生支持 removeIf(),一行代码搞定条件批量删,语义清楚、线程安全(不会抛 ConcurrentModificationException)、性能也好。它内部用迭代器实现,自动处理索引偏移问题。
比如删掉所有长度大于 3 的字符串:
list.removeIf(s -> s.length() > 3);
删掉所有 null 或空字符串:
list.removeIf(s -> s == null || s.trim().isEmpty());
先筛选再批量删(适合复杂逻辑或老版本 JDK)
如果条件判断较重(比如要查数据库、调外部接口),或者项目还在用 JDK 7 及以下,可先收集待删元素,再用 removeAll() 批量清除。
- 注意:不能直接用原始 list 做筛选源并同时删——会出错
- 稳妥做法是先复制一份用于遍历:new ArrayList(list)
- 或者用 Stream 收集:list.stream().filter(...).collect(Collectors.toList())
示例:删掉所有偶数(用 Stream + removeAll):
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
List
list.removeAll(toRemove);
避免踩坑的常见错误写法
这些写法看着简单,但实际会漏删、越界或崩溃:
- 增强 for 循环里直接调 list.remove() → 抛 ConcurrentModificationException
- 正向 for 循环 + remove() 后不调整 i → 删完一个,下一个被跳过
- 把 list.size() 提前存成变量再循环 → size 实时变,i 可能越界
真要用 for 循环,必须倒序(for (int i = list.size() - 1; i >= 0; i--)),且用 remove(int index) 删除。
按内容批量删 vs 按条件批量删的区别
如果只是删几个已知值(比如“苹果”“香蕉”),用 removeAll(Arrays.asList("苹果", "香蕉")) 更快更直观;
但只要判断逻辑依赖元素自身属性(如“价格 > 100”“状态为已失效”),就该选 removeIf() 或先 filter 再 removeAll——它才是真正意义上的“按条件”批量删。










