ArrayList批量删除应避免边遍历边remove(),推荐Iterator.remove()、倒序索引删除、removeAll()或新建列表;核心是减少数组复制次数,避免O(n²)退化。

ArrayList 的批量删除不推荐边遍历边调用 remove(),否则会因数组元素频繁搬移导致时间复杂度退化为 O(n²)。高效做法是“标记 + 一次搬移”或“倒序索引删除”,核心是减少底层数组的复制次数。
使用 Iterator 的 remove() 安全批量删
适用于按条件动态判断是否删除(如删掉所有 null 或满足某 predicate 的元素):
- Iterator 的
remove()是唯一安全的遍历中删除方式,它内部记录了上次返回的索引,能正确维护游标并避免ConcurrentModificationException - 每次删除只触发一次
System.arraycopy向前搬移,但若删除频繁,仍可能多次搬移 - 示例:List<String> list = new ArrayList(Arrays.asList("a", "b", "c", "b")); Iterator<String> it = list.iterator(); while (it.hasNext()) { if ("b".equals(it.next())) it.remove(); }
先收集索引,再倒序删除(推荐用于已知要删哪些位置)
当你已有待删元素的下标(比如从另一个集合查出的索引列表),倒序删除可避免索引偏移问题,且每删一个,前面的元素无需重新搬移:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 对索引列表按降序排序(如
Collections.sort(indices, Collections.reverseOrder())) - 遍历该排序后的索引列表,逐个调用
list.remove(index) - 因为从高到低删,每次删除不影响尚未处理的索引值,也不触发无效搬移
用 removeAll() 批量删对象(适合删已知元素集合)
如果目标是删掉一批具体对象(而非按条件),removeAll(Collection<?>) 是简洁选择:
立即学习“Java免费学习笔记(深入)”;
- 底层会先转成 HashSet 加速查找(平均 O(1)),再遍历原 list,对每个元素检查是否在待删集合中,仅保留不匹配的元素
- 最终通过一次
System.arraycopy把保留的元素紧凑复制到开头,再设 size 截断——本质是“标记保留项 + 一次搬移” - 注意:要求元素正确实现
equals();若 list 很大而待删集合很小,手动遍历+标记可能更省内存
手动构建新列表(最可控,适合大数据量过滤)
当批量删除逻辑复杂(如多条件组合、需同时做转换),直接新建 ArrayList 并只 add 保留项,效率最高且语义清晰:
- 避免任何删除开销,只有一次遍历 + 一次数组扩容(可预估容量避免多次扩容)
- 示例:List<String> keep = new ArrayList<>(list.size()); for (String s : list) { if (!shouldRemove(s)) keep.add(s); } list.clear(); list.addAll(keep);
- 若允许替换原引用,甚至可直接
list = keep;,更轻量

















