java迭代器失效
2013-02-25 13:37
309 查看
今天在测试代码的时候出现一个异常ConcurrentModificationException,该异常网上很多解决方案以及解释,但我还是再记录一遍吧。
代码抽象出来是这样的:
该代码在运行期间就出现java.util.ConcurrentModificationException异常。
这个循环其实是对list进行迭代。
1.在迭代的时候怎么判断是否还有下一个(hasNext()方法怎么实现):
cursor:Index of element to be returned by subsequent call to next
size():是该list的size
所以只要两者不相等,就认为还有元素。
2.迭代的时候怎么取下一个(next()方法怎么实现):
modelCount:The number of times this list has been <i>structurally modified</i>.Structural modifications are those that change the size of the list, or otherwise perturb it in such a fashion that iterations in progress may yield incorrect results.
expectedModCount:期望的modelCount
这2个变量是有迭代器自己来维护的。
上面这段程序出现异常是因为我们使用Collection里面的remove方法进行删除,ArrayList的remove方法实现:
modCount+1,导致modCount和expectedModCount不相等。
3.解决方法就是用迭代器自己的remove方法:
代码抽象出来是这样的:
import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) { List<Integer> list=new ArrayList<Integer>(); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5); for (Integer i : list) {//这是迭代 if(i==3){ list.remove(new Integer(i));//引起异常的操作 } } } }
该代码在运行期间就出现java.util.ConcurrentModificationException异常。
这个循环其实是对list进行迭代。
1.在迭代的时候怎么判断是否还有下一个(hasNext()方法怎么实现):
public boolean hasNext() { return cursor != size(); }
cursor:Index of element to be returned by subsequent call to next
size():是该list的size
所以只要两者不相等,就认为还有元素。
2.迭代的时候怎么取下一个(next()方法怎么实现):
public E next() { checkForComodification(); try { E next = get(cursor); lastRet = cursor++; return next; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } }
final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }
modelCount:The number of times this list has been <i>structurally modified</i>.Structural modifications are those that change the size of the list, or otherwise perturb it in such a fashion that iterations in progress may yield incorrect results.
expectedModCount:期望的modelCount
这2个变量是有迭代器自己来维护的。
上面这段程序出现异常是因为我们使用Collection里面的remove方法进行删除,ArrayList的remove方法实现:
public boolean remove(Object o) { if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; }
private void fastRemove(int index) { modCount++; //*** int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // Let gc do its work }
modCount+1,导致modCount和expectedModCount不相等。
3.解决方法就是用迭代器自己的remove方法:
public void remove() { if (lastRet == -1) throw new IllegalStateException(); checkForComodification(); try { AbstractList.this.remove(lastRet); //将modCount+1,实现如下 if (lastRet < cursor) cursor--; lastRet = -1; expectedModCount = modCount; //维护 } catch (IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } }
public E remove(int index) { RangeCheck(index); modCount++; //*** E oldValue = (E) elementData[index]; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // Let gc do its work return oldValue; }
相关文章推荐
- STL 迭代器失效问题
- STL map 内存改变,迭代器失效,_Isnil(_Ptr)和红黑树
- 使用迭代器遍历集合时,当集合中的数据发生变化是会抛出java.util.ConcurrentModificationException异常
- 详解Spring中的CharacterEncodingFilter--forceEncoding为true在java代码中设置失效--html设置编码无效?不知真假
- map等关联容器 vector等序列容器 如何防止迭代器失效 即erase()的使用
- Java学习之Iterator(迭代器)的一般用法 (转)
- JAVA HashMap单key多value的实现及迭代器打印(附源码)
- java List集合,迭代器iterator
- Java中容器[Collection(List,Set,Queue),Map],迭代器(Iterator)和比较器(Comparator)及列表排序
- Java迭代器
- Java之集合框架 List接口的特有方法、迭代器的并发修改异常以及LinkedList特有方法
- STL容器 迭代器失效总结
- Java日记_17.9.01——点击按钮后,键盘监听失效的原因与解决办法
- std::map中迭代器失效的问题
- 【STL源码剖析读书笔记】STL容器迭代器失效问题总结
- STL容器特征总结和迭代器失效
- Java设置session超时(失效)的三种方式
- 迭代器_HashMap分拣思路与面向对象组合解题JAVA_119-121
- java迭代器Iterator和foreach循环
- STL容器迭代器失效问题