ArryList java.util.ConcurrentModificationException异常
来源:互联网 发布:北京seo推广推荐 编辑:程序博客网 时间:2024/06/05 18:53
我们一般使用ArryList做循环遍历的时候,会删除某个元素。
以下是我们的list :
ArryList
List<String> list=new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); list.add("e"); list.add("f"); list.add("g");
输出list
for(String s1:list){ System.err.println(s1); }
一下是两种做法:
做法1:
for(int i=0;i<list.size();i++){ if(list.get(i).equals("c")){ list.remove(i); } }
输出结果:
abdefg
做法2:
for(String s1:list){ if(s1.equals("c")){ list.remove(s1); } }
输出结果:
Exception in thread "main" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901) at java.util.ArrayList$Itr.next(ArrayList.java:851) at Test.main(Test.java:27)
做法3:
Iterator it=list.iterator(); while(it.hasNext()){ if(it.next().equals("c")){ it.remove(); } }
输出结果:
abdefg
做法4 :
List<String> deleteList=new ArrayList<>(); for(String s1:list){ if(s1.equals("c")){ deleteList.add(s1); } } list.removeAll(deleteList);
输出结果:
abdefg
以上,我们可以看到 做法1 3 是不会抛异常 做法2 抛了个异常。 做法4 是另一种解决问题的方式
在我们以后的开发中 使用 1 3 4 来删除list中特定的元素。
现在让我们来看看 异常产生的原因。
做法2 我们使用了foreach 的写法。 这个是 Iterator 接口提供的 快速遍历方式,对比做法1 发现这种写法很简单 很好记。
iterator 有四个 方法:
1 boolean hasNext(); 2 E next(); 3 default void remove() { throw new UnsupportedOperationException("remove"); } 4 default void forEachRemaining(Consumer<? super E> action) { Objects.requireNonNull(action); while (hasNext()) action.accept(next()); }
我们的ArryList 有一个内部类 Itr 实现了 iterator 接口。 分别 重写 了
hasNext next remove forEachRemaining 方法
itr 内部类 部分:
private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount;
而我们 使用的 foreach 主要使用的是 hasNext next 方法
先看看 两种的具体实现
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]; }
可以看到 在每次的next中 都有一个 :
checkForComodification(); //方法 final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }
在使用 foreach 遍历的时 内部类中会有 int expectedModCount = modCount;
modCount 表示修改次数。 如果在遍历的时候 删除了元素 做法2
则modCount 的值会改变。 此时 在调用 next 的时候会出现 expectedModCount != modCount
则会抛出异常。
而如果使用 内部的 remove 方法 在romove 中会有
expectedModCount = modCount;
则不会抛异常。
- ArryList java.util.ConcurrentModificationException异常
- 异常:java.util.ConcurrentModificationException
- java.util.ConcurrentModificationException异常
- java.util.ConcurrentModificationException异常
- java.util.ConcurrentModificationException 异常
- 异常:java.util.ConcurrentModificationException
- 异常:java.util.ConcurrentModificationException
- java.util.ConcurrentModificationException 异常
- java.util.ConcurrentModificationException 异常
- java.util.ConcurrentModificationException异常
- java.util.ConcurrentModificationException异常
- java.util.ConcurrentModificationException异常
- java.util.ConcurrentModificationException异常
- java.util.ConcurrentModificationException异常
- java.util.ConcurrentModificationException异常
- java.util.ConcurrentModificationException异常
- java.util.ConcurrentModificationException异常
- java.util.ConcurrentModificationException异常
- 数据库oracle,pgsq,mysql.相关设置
- HTML 语言代码参考手册
- 【图像处理】图像的极坐标变换
- c++中指针与引用的区别
- 蓝鸥Unity入门刚体学习笔记
- ArryList java.util.ConcurrentModificationException异常
- Ubuntu配置和修改IP地址
- AFN调用webservice
- 拦截器和过滤器的区别
- mysql+spring+mybatis实现数据库读写分离[代码配置]
- iOS学习笔记-054.自定义View02——小黄人
- Python 造轮子/现有轮子 相关资料
- 技术面试之HR面试题
- 整理时下流行的浏览器User-Agent大全