码迷,mamicode.com
首页 > 其他好文 > 详细

ArrayList、LinkedList的迭代器问题

时间:2015-11-12 18:28:11      阅读:251      评论:0      收藏:0      [点我收藏+]

标签:

不知道大家遇到过这样 的代码段没有

List<String> list = new LinkedList<String>();
list.add("A");
list.add("B");
list.add("C");
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()) {
    list.add("D");   /*   list.set(0,"AA");*/    System.out.println(iterator.next());
}


我就曾经无意之中写过这样的代码段,程序在运行的时候报错java.util.ConcurrentModificationException。打开源码发现,每次在迭代器生成之后,要是用list.add() list.remove()方法改变链表或者数组的结构,迭代器操作都会报这个错误。我们贴出来源码看看为啥。

public E next() {
    checkForComodification();(0)
    if (!hasNext())
        throw new NoSuchElementException();
    lastReturned = next;(1)
    next = next.next;
    nextIndex++;(2)
    return lastReturned.item;
}

(0)这个过程就是跑错的地方,也就是说迭代器不允许我们再修改被引用的链表结构。  next、nextIndex都是初始化迭代器的时候赋值的。

ListItr(int index) {
    // assert isPositionIndex(index);
    next = (index == size) ? null : node(index);
    nextIndex = index;
}

如果没有(0),我们用list.add("D"); 这样的代码改变了原来的list结构,那么(2)中的
nextIndex
不会是原来的值了。这样就会导致取值混乱。
举个栗子
链表
1--》2--》3--》4
在迭代器到达2的时候,用add方法在2之前给链表添加一个值
1--》D-->2--》3--》4而此时nextIndex依然在2,下次获取值又获取到了数据2,导致遍历链表数据混乱。所以在迭代器创建之后,不允许再修改被引用链表的结构。另外,迭代器是非线程安全的,api建议我们使用 List list = Collections.synchronizedList(new LinkedList(...))
保证线程安全。


ArrayList、LinkedList的迭代器问题

标签:

原文地址:http://my.oschina.net/zjItLife/blog/529474

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!