List删除元素报Exception in thread "main" java.util.ConcurrentModificationException异常,或数据删除不完整
来源:互联网 发布:骰子软件 编辑:程序博客网 时间:2024/06/05 16:54
先定义测试list
public static List<String> list = new ArrayList<String>();static{list.add("a");list.add("b");list.add("c");list.add("d");list.add("c");list.add("c");list.add("a");list.add("c");list.add("a");list.add("c");}
这里我主要用到三种方法:
1、Iterator迭代删除(建议使用)
public static List removeIterator(){Iterator<String> it = list.iterator();while(it.hasNext()){String t = it.next();if(t.equals("c")){//list.remove(t);//用list移除会报ConcurrentModificationException异常it.remove();}}return list;}用iterator迭代基本都能删除,但是用list.remove()删除的话会报ConcurrentModificationException异常,可以debug进去看下异常:final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }expectedModCount:表示对ArrayList修改次数的期望值,它的初始值为modCount。
modCount :AbstractList类中的一个成员变量,list里add、remove等操作都会使modCount++。但在多线程下时用iterator.remove()也会报ConcurrentModificationException异常,并不全在于ArrayList是非线程安全的,换成线程安全Vector也同样会报ConcurrentModificationException异常
原因在于,虽然Vector的方法采用了synchronized进行了同步,但是由于Vector是继承的AbstarctList,因此通过Iterator来访问容器的话,事实上是不需要获取锁就可以访问。那么显然,由于使用iterator对容器进行访问不需要获取锁,在多线程中就会造成当一个线程删除了元素,由于modCount是AbstarctList的成员变量,因此可能会导致在其他线程中modCount和expectedModCount值不等。
解决办法:
1)在使用iterator迭代的时候使用synchronized或者Lock进行同步;
参考:http://www.jianshu.com/p/02a08c6c21ed
2)使用并发容器CopyOnWriteArrayList代替ArrayList和Vector。
2、基本下标for循环
public static List removeFor(){for(int i=0;i<list.size();i++){if("c".equals(list.get(i))){//删除为c的元素list.remove(i);System.out.println(list.size());//会根据remove减少,数组元素往前移,后面的会用null填补}}System.out.println(list.toString());//输出结果:[a, b, d, c, a, a] 但是还有一个c元素并没有删除
return list;}因为下标4和5里的元素都为c,下标为4的删了,下标为5的元素移至下标为4中,但迭代值i会一直累加,所以并不会再遍历到这个内容为c的元素中,
如果要删除的元素不相邻的话是可以实现要求的。
3、增强for循环
3.1用list.remove()后还继续循环依然会报ConcurrentModificationException异常
public static List removeForeach(){for(String s:list){if("c".equals(s)){list.remove(s);}}return list;}
3.2但是remove()后跳出循环就不会报异常public static List removeForeach(){for(String s:list){if("c".equals(s)){list.remove(s);break;//不跳出循环,会报ConcurrentModificationException异常}}return list;}
- List删除元素报Exception in thread "main" java.util.ConcurrentModificationException异常,或数据删除不完整
- 异常:Exception in thread "main" java.util.ConcurrentModificationException
- Exception in thread "main" java.util.ConcurrentModificationException
- Exception in thread "main" java.util.ConcurrentModificationException
- Exception in thread "main" java.util.ConcurrentModificationException
- Exception in thread "main" java.util.ConcurrentModificationException
- JAVA List 一边遍历一边删除元素,报java.util.ConcurrentModificationException异常
- Map中删除数据报:java.util.ConcurrentModificationException异常
- java -- Exception in thread "main" java.util.ConcurrentModificationException
- 多线程报错 : Exception in thread "Thread-3" java.util.ConcurrentModificationException 并发修改异常
- 解决“Exception in thread "main" java.util.ConcurrentModificationException”异常的办法
- 遍历集合时出现的异常Exception in thread "main" java.util.ConcurrentModificationException
- 遍历集合时出现的异常Exception in thread "main" java.util.ConcurrentModificationException
- java 遍历list、set时 删除元素 java.util.ConcurrentModificationException
- Android 集合操作关于Exception in thread "main" java.util.ConcurrentModificationException
- java set 删除元素 java.util.ConcurrentModificationException
- Exception in thread "Thread-6" java.util.ConcurrentModificationException
- Exception in thread "main" java.util.InputMismatchException
- AtomicReference(无锁的对象引用)与AtomicStampedReference与(带有时间戳的对象引用)
- JAVA学习日记----------
- 1008. 数组元素循环右移问题 (20) Python 2编译
- 黑白棋算法简单实现与基于Qt的GUI编程的综合应用
- Java基础教程35-LinkedList和ArrayListed的区别
- List删除元素报Exception in thread "main" java.util.ConcurrentModificationException异常,或数据删除不完整
- Kotlin学习(二)——基本命令行操作hello world
- 被低估的BIRT报表(二):Birt也可以很漂亮
- 从vue文件中抽取出子组件的流程及过程中踩过的坑
- Opencv绘制灰度/彩色图像的直方图及直方图的均衡化实例及源代码
- 蓝牙模块调试笔记
- 51nod 1580 铺管道
- Android 创建自定义控件
- 单例模式之:高效非同步方法实现