首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >幻数ConcurrentModificationException

幻数ConcurrentModificationException
EN

Stack Overflow用户
提问于 2014-08-28 09:23:08
回答 1查看 112关注 0票数 3

我正在使用下面的代码测试集合的ConcurrentModificationException

代码语言:javascript
复制
public static void main(String[] args) {
    ArrayList<String> list = new ArrayList<String>();
    list.add("a");
    list.add("b");
    list.add("c");

    for (String s : list) {
     // if (s.equals("a")) { // ConcurrentModificationException!
        if (s.equals("b")) { // -->> Magic number, NO Exception, Why? 
     // if (s.equals("c")) { // ConcurrentModificationException!
            list.remove(s);
        }
    }
    System.out.println(list);
}

我不明白为什么删除"b“是可以的,但其他NG呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-08-28 09:46:46

首先要知道的是(如JLS中所述)以下增强的for循环:

代码语言:javascript
复制
for (String s : list) {
    // Do something with s
}

相当于:

代码语言:javascript
复制
for (Iterator<String> it = list.iterator(); it.hasNext();) {
    String s = it.next();
    // Do something with s
}

如果您查看AbstractList中迭代器的实现,您将看到:

  • hasNext()不检查并发修改,只检查我们是否在列表的末尾,使用它的大小: 公共布尔值hasNext() {返回游标!= size();}
  • next()所做的第一件事是调用checkForComodification(),查看在迭代过程中是否修改了列表: 公共e(){ checkForComodification();尝试{e=get(游标);lastRet = cursor++;返回next;} catch (IndexOutOfBoundsException e) { checkForComodification();抛出新的NoSuchElementException();}ConcurrentModificationException(){ if (modCount != expectedModCount)抛出新的ConcurrentModificationException()};

因此,当您迭代和删除列表的倒数第二个元素时,下一个指令将是对hasNext()的调用,它将返回false,因为删除一个元素会导致列表的大小减少一个,并且您的迭代将停止而不调用next()并抛出一个Exception

顺便说一句,所有这些只是一个实现细节,您不应该依赖它,因为它可能会改变,并且在迭代时使用it.remove()从列表中删除元素。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25545242

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档