首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >旧的for-each循环有效,新的for-each循环获取ConcurrentModificationException

旧的for-each循环有效,新的for-each循环获取ConcurrentModificationException
EN

Stack Overflow用户
提问于 2015-08-17 23:22:12
回答 3查看 179关注 0票数 0

根据我所读到的,我知道当你试图编辑一个列表时,当它还在迭代时,你会得到一个ConcurrentModificationException。

现在我不明白的是,为什么旧的foreach循环没有给出异常,而新的foreach循环却给出了呢?

代码语言:javascript
复制
public void newForeachLoop() {
    for (Person person : list) {
        if (person.getPosition().equals(this.getPosition())) {
            list.remove(person);
        }
    }
}

public void oldForeachLoop() {
    for (int i = 0; i < list.size(); i++) {
        if (list.get(i).getPosition().equals(this.getPosition())) {
            list.remove(list.get(i));
        }
    }
}
EN

回答 3

Stack Overflow用户

发布于 2015-08-17 23:32:02

在旧的循环中,您使用列表迭代器而不是,而是使用列表中对象的计数。

在新的循环中,您使用的是内置迭代器,它是指向该实例的指针。当您从列表中删除一个项目时,您正在修改该实例并重置迭代器,从而抛出异常。

票数 1
EN

Stack Overflow用户

发布于 2015-08-19 14:53:11

因为for each循环是基于迭代器的,所以不能在迭代元素时将其从列表中删除。您甚至可以尝试显式地使用迭代器和删除元素。

代码语言:javascript
复制
    List<String> list= new ArrayList <String>;
    list.add("One");
    list.add("two");
    list.add("three");

    Iterator listItr = list.iterator () ;
    while ( listItr.hasNext() )
    {
      String countStr = itr.next();
      if ( countStr.equals ("two"))
          itr.remove(); //will not throw any exception

     //if you do it list.remove (countStr) //will throw exception 
    }  

在迭代时使用index从列表中删除一个元素,肯定不会抛出任何异常,但你需要格外小心修改它的长度。甚至更多元素的索引也会受到您的操作的干扰。所以,如果你处理好这个问题,就不成问题了。

票数 1
EN

Stack Overflow用户

发布于 2015-08-19 15:05:31

正如@SacJn解释的那样,当通过iterator()迭代时,你不能在List中进行结构上的改变(例如添加或删除元素)。iterator()将检测到不一致并抛出ConcurrentModificationException。在Java-8中,有一种干净而安全的方法来解决您的任务:

代码语言:javascript
复制
public void java8Solution() {
    list.removeIf(person -> person.getPosition().equals(this.getPosition()));
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32054068

复制
相关文章

相似问题

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