深入理解Java的迭代器Iterator

来源:互联网 发布:许继和南瑞 知乎 编辑:程序博客网 时间:2024/05/16 09:14

先看一段代码:

package com.thinking4java;import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class ListModifyDemo {public static void main(String[] args) {List<Integer> list = new ArrayList<Integer>();list.add(10);list.add(20);list.add(30);Iterator<Integer> iter = list.iterator();while (iter.hasNext()) {Integer next = iter.next();System.out.println("next=" + next);list.add(40);}}}

next=10Exception in thread "main" java.util.ConcurrentModificationExceptionat java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)at java.util.AbstractList$Itr.next(AbstractList.java:343)at com.thinking4java.ListModifyDemo.main(ListModifyDemo.java:16)

Iterator的工作机制。Iterator是工作在一个独立的线程中,并且拥有一个 mutex锁,就是说Iterator在工作的时候,是不允许被迭代的对象被改变的。Iterator被创建的时候,建立了一个内存索引表(单链表),这 个索引表指向原来的对象,当原来的对象数量改变的时候,这个索引表的内容没有同步改变,所以当索引指针往下移动的时候,便找不到要迭代的对象,于是产生错 误。List、Set等是动态的,可变对象数量的数据结构,但是Iterator则是单向不可变,只能顺序读取,不能逆序操作的数据结构,当 Iterator指向的原始数据发生变化时,Iterator自己就迷失了方向。

再回过头看下List迭代器的源码:

……

public Iterator<E> iterator() {return new Itr();}private class Itr implements Iterator<E> {/** * Index of element to be returned by subsequent call to next. */int cursor = 0;/** * Index of element returned by most recent call to next or previous. * Reset to -1 if this element is deleted by a call to remove. */int lastRet = -1;/** * The modCount value that the iterator believes that the backing List * should have. If this expectation is violated, the iterator has * detected concurrent modification. */int expectedModCount = modCount;public boolean hasNext() {return cursor != size();}public E next() {checkForComodification();try {E next = get(cursor);lastRet = cursor++;return next;} catch (IndexOutOfBoundsException e) {checkForComodification();throw new NoSuchElementException();}}public void remove() {if (lastRet == -1)throw new IllegalStateException();checkForComodification();try {AbstractList.this.remove(lastRet);if (lastRet < cursor)cursor--;lastRet = -1;expectedModCount = modCount;} catch (IndexOutOfBoundsException e) {throw new ConcurrentModificationException();}}final void checkForComodification() {
//此处的modCount是Itr的外部类即:AbstractList的属性(protected transient int modCount = 0;)if (modCount != expectedModCount)throw new ConcurrentModificationException();}}


原创粉丝点击