千家信息网

怎么解决Java List的remove()方法踩坑

发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,这篇文章主要讲解了"怎么解决Java List的remove()方法踩坑",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"怎么解决Java List的re
千家信息网最后更新 2025年11月07日怎么解决Java List的remove()方法踩坑

这篇文章主要讲解了"怎么解决Java List的remove()方法踩坑",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"怎么解决Java List的remove()方法踩坑"吧!

Java的List在删除元素时,一般会用list.remove(o)/remove(i)方法。在使用时,容易触碰陷阱,得到意想不到的结果。总结以往经验,记录下来与大家分享。

首先初始化List,代码如下:

package com.cicc.am.test; import java.util.ArrayList;import java.util.List; public class ListTest {  public static void main(String[] args) {  List list=new ArrayList();  list.add(1);  list.add(2);  list.add(3);  list.add(3);  list.add(4);  System.out.println(list); }}

输出结果为[1, 2, 3, 3, 4]

1、普通for循环遍历List删除指定元素--错误!!!

for(int i=0;i

输出结果:[1, 2, 3, 4]

为什么元素3只删除了一个?本以为这代码再简单不过,可还是掉入了陷阱里,上面的代码这样写的话,元素3是过滤不完的。只要list中有相邻2个相同的元素,就过滤不完。List调用remove(index)方法后,会移除index位置上的元素,index之后的元素就全部依次左移,即索引依次-1要保证能操作所有的数据,需要把index-1,否则原来索引为index+1的元素就无法遍历到(因为原来索引为index+1的数据,在执行移除操作后,索引变成index了,如果没有index-1的操作,就不会遍历到该元素,而是遍历该元素的下一个元素)。

如果这样,删除元素后同步调整索引或者倒序遍历删除元素,是否可行呢?

2、for循环遍历List删除元素时,让索引同步调整--正确!

for(int i=0;i

输出结果:[1, 2, 4]

3、倒序遍历List删除元素--正确!

for(int i=list.size()-1;i>=0;i--){ if(list.get(i)==3){  list.remove(i); }}System.out.println(list);

输出结果:[1, 2, 4]

4、foreach遍历List删除元素--错误!!!

for(Integer i:list){    if(i==3) list.remove(i);}System.out.println(list);

抛出异常:java.util.ConcurrentModificationException

foreach 写法实际上是对的 Iterable、hasNext、next方法的简写。因此从List.iterator()源码着手分析,跟踪iterator()方法,该方法返回了 Itr 迭代器对象。

  public Iterator iterator() {        return new Itr();    }

Itr 类定义如下:

private class Itr implements Iterator {        int cursor;       // index of next element to return        int lastRet = -1; // index of last element returned; -1 if no such        int expectedModCount = modCount;         public boolean hasNext() {            return cursor != size;        }         @SuppressWarnings("unchecked")        public E next() {            checkForComodification();            int i = cursor;            if (i >= size)                throw new NoSuchElementException();            Object[] elementData = ArrayList.this.elementData;            if (i >= elementData.length)                throw new ConcurrentModificationException();            cursor = i + 1;            return (E) elementData[lastRet = i];        }         public void remove() {            if (lastRet < 0)                throw new IllegalStateException();            checkForComodification();             try {                ArrayList.this.remove(lastRet);                cursor = lastRet;                lastRet = -1;                expectedModCount = modCount;            } catch (IndexOutOfBoundsException ex) {                throw new ConcurrentModificationException();            }        }         final void checkForComodification() {            if (modCount != expectedModCount)                throw new ConcurrentModificationException();        }    }

通过代码我们发现 Itr 是 ArrayList 中定义的一个私有内部类,在 next、remove方法中都会调用checkForComodification 方法,该方法的 作用是判断 modCount != expectedModCount是否相等,如果不相等则抛出ConcurrentModificationException异常。每次正常执行 remove 方法后,都会对执行expectedModCount = modCount赋值,保证两个值相等,那么问题基本上已经清晰了,在 foreach 循环中

执行 list.remove(item);,对 list 对象的 modCount 值进行了修改,而 list 对象的迭代器的 expectedModCount 值未进行修改,因此抛出了ConcurrentModificationException异常。

5、迭代删除List元素--正确!

java中所有的集合对象类型都实现了Iterator接口,遍历时都可以进行迭代:

Iterator it=list.iterator(); while(it.hasNext()){  if(it.next()==3){   it.remove();  }        }System.out.println(list);

输出结果:[1, 2, 4]

Iterator.remove() 方法会在删除当前迭代对象的同时,会保留原来元素的索引。所以用迭代删除元素是最保险的方法,建议大家使用List过程

中需要删除元素时,使用这种方式。

6、迭代遍历,用list.remove(i)方法删除元素--错误!!!

Iterator it=list.iterator(); while(it.hasNext()){  Integer value=it.next();   if(value==3){   list.remove(value);  } }System.out.println(list);

抛出异常:java.util.ConcurrentModificationException,原理同上述方法4.

7、List删除元素时,注意Integer类型和int类型的区别.

上述Integer的list,直接删除元素2,代码如下:

list.remove(2);System.out.println(list);

输出结果:[1, 2, 3, 4]

可以看出,List删除元素时传入数字时,默认按索引删除。如果需要删除Integer对象,调用remove(object)方法,需要传入Integer类型,代码如下:

list.remove(new Integer(2));System.out.println(list);

输出结果:[1, 3, 3, 4]

感谢各位的阅读,以上就是"怎么解决Java List的remove()方法踩坑"的内容了,经过本文的学习后,相信大家对怎么解决Java List的remove()方法踩坑这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

元素 方法 索引 结果 输出 迭代 代码 对象 类型 错误 学习 循环 倒序 内容 数据 问题 陷阱 保证 同步 调整 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 安卓软件开发难么 未成年人网络安全定义 文科可以学网络技术吗 数据库应用技术试题1256 软件开发企业有什么资质证书 信息网络安全监察专业考公务员 豫教思语网络安全知识竞赛 数据库技术及应用需要电脑 对服务器暴力破解会产生什么后果 服务器和小纵谁是杀手 国家网络安全特辑报道稿 mysql数据库原理介绍 tomcat服务器证书 网络安全宣传周 领导讲话 昌平区运营网络技术软件 武都软件开发 牟平区平台软件开发推荐 服务器没有检测到有响应 黑客文化与网络安全答案知乎 建立山水资源活力数据库 怎么直接修改数据库 寒假期间护苗.网络安全课 天津水性软件开发试验设备 软件开发中属于设计阶段的是 计算机软件开发实训心得 抖影工厂软件开发 申论 网络安全个人作文 将微信头像直接存入数据库 linux数据库的迁移备份 常见软件开发面试技术问题
0