Java中ArrayList删除元素需区分remove(Object)按值删首匹配项和remove(int)按索引删指定位置;批量删所有匹配项应倒序遍历、用Iterator.remove()或removeIf()。

Java 中 ArrayList 删除元素主要有两种场景:按值删除(指定元素)和按索引删除(指定位置)。关键要区分 remove(Object) 和 remove(int) 两个重载方法,否则容易误删或报错。
按值删除(删除第一个匹配的元素)
调用 remove(Object o) 方法,它会从头开始遍历,删除**第一个等于该对象**的元素(使用 equals() 判断),返回 true 表示删除成功,false 表示未找到。
- 注意:传入的是元素本身(如字符串、数字包装类等),不是索引
- 如果元素为
null,会删除第一个null值 - 对自定义对象,需确保正确重写了
equals()(和hashCode())
示例:
ArrayList<String> list = new ArrayList<>(Arrays.asList("a", "b", "c", "b"));
list.remove("b"); // 删除第一个 "b" → ["a", "c", "b"]按索引删除(删除指定位置的元素)
调用 remove(int index) 方法,直接删除指定下标处的元素(0 起始),返回被删元素。若索引越界(< 0 或 >= size()),抛出 IndexOutOfBoundsException。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
立即学习“Java免费学习笔记(深入)”;
- 这是真正“删位置”,不是删值
- 删除后,后续元素自动前移,集合大小减 1
- 安全做法:删除前检查
index >= 0 && index < list.size()
示例:
ArrayList<Integer> nums = new ArrayList<>(Arrays.asList(10, 20, 30)); nums.remove(1); // 删除索引 1 处的 20 → [10, 30]
批量删除多个相同元素(非首匹配)
如果想删掉所有匹配项(不止第一个),不能用单次 remove(Object),因为会跳过后续元素(下标变化导致漏判)。推荐以下方式:
-
倒序遍历 + 按索引删:从
size()-1往 0 遍历,避免下标偏移 - Iterator.remove():安全迭代中删除(唯一推荐的边遍历边删方式)
- removeIf()(Java 8+):简洁高效,内部用迭代器实现
示例(全部删 "b"):
// 方式1:倒序 for
for (int i = list.size() - 1; i >= 0; i--) {
if ("b".equals(list.get(i))) list.remove(i);
}
<p>// 方式2:Iterator
for (Iterator<String> it = list.iterator(); it.hasNext(); ) {
if ("b".equals(it.next())) it.remove();
}</p><p>// 方式3:removeIf(最简)
list.removeIf("b"::equals);注意事项与常见坑
-
别混淆重载方法:写
list.remove(0)是删索引 0;写list.remove((Integer)0)才是删值为 0 的元素(因自动装箱,int字面量 0 会被当成索引) -
基本类型数组列表慎用:如
ArrayList<int>不合法,只能用包装类Integer;但list.remove(0)在这种情况下永远删索引 -
并发修改异常:用普通 for 或增强 for 遍历时调用
remove()会触发ConcurrentModificationException,必须用Iterator.remove()或removeIf() - 性能考虑:按值删除需遍历,时间复杂度 O(n);按索引删除是 O(n),因后续元素要移动

















