java源码分析(12)-ConcurrentModificationException
2016-07-06 23:01
423 查看
ConcurrentModificationException
此异常在使用迭代器时经常出现,主要原因为迭代器迭代未完成之前,容器属性被更改。例如下面的一段程序:
所以,在使用迭代器时,若需要移除数据,请使用迭代器的remove方法,程序代码改为以下即可:
此异常在使用迭代器时经常出现,主要原因为迭代器迭代未完成之前,容器属性被更改。例如下面的一段程序:
public static void main(String[] args) { ArrayList<Integer> list=new ArrayList<Integer>(); list.add(1); list.add(2); list.add(3); Iterator<Integer> iterator=list.iterator(); while(iterator.hasNext()){ Integer i=iterator.next(); if(i==1){ list.remove(i); } } }如上图的代码所示,便会报ConcurrentModificationException异常,原因为在使用迭代器时,又使用了list的remove方法,使list的属性发生了变化,但却通知迭代器,迭代器在下次循环时发现容器属性发生变化而报错。下面请看源码
</pre><pre name="code" class="java">public Iterator<E> iterator() { return new Itr(); } private class Itr implements Iterator<E> { int cursor; //迭代器next指向的下标 int lastRet = -1; //现在指向的下标 int expectedModCount = modCount;//modCount为AbstractList中定义的属性,用于记录list被更改 的次数 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;//可以看到迭代器中的remove方法在移除元素后,还将修改后的modCount通知了迭代器,使迭代过程中的list属性保持一致 } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount)//判断有效性,在迭代过程中,若出现非迭代器更改list的情况,将会抛异常以此来保证list属性的一致性 throw new ConcurrentModificationException(); } }
所以,在使用迭代器时,若需要移除数据,请使用迭代器的remove方法,程序代码改为以下即可:
public static void main(String[] args) { ArrayList<Integer> list=new ArrayList<Integer>(); list.add(1); list.add(2); list.add(3); Iterator<Integer> iterator=list.iterator(); while(iterator.hasNext()){ Integer i=iterator.next(); if(i==1){ iterator.remove(); } } }
相关文章推荐
- Struts(四)
- 快速排序——java
- Struts(三)
- 归并排序——java
- java冒泡排序和选择排序法
- WAS的SystemOut.log中报错“ADMS0015E”
- Java-JDBC调用批处理、存储过程、事务
- java问题整理
- java web常用数据库地址
- Android中JNI使用详解(1)---Eclipse中NDK配置So文件生成
- [leetcode-327]Count of Range Sum(java)
- 【SSH】——Struts由来以及基本原理
- 学习笔记-Java中的xml文件读取之DOM解析
- 【Struts2文件下载】struts.xml文件中配置action,访问路径问题
- 使用 Hibernate Tools 自动生成hbm.xml及model java文件
- java文件上传!针对各种文件上传demo实列 文件上传以及数据库保存文件名以及路径名称:
- (2)使用JDK开发WebService
- 如何在eclipse安装windowbuilder插件
- unreachable code 报错
- JAVA 三大版本