旧的for-each循环工作,新的for-each循环获得ConcurrentModificationException

时间:2015-08-17 15:22:12

标签: java loops exception foreach

从我所阅读的内容中我了解到,当您尝试编辑列表时,如果仍在进行迭代,则会收到ConcurrentModificationException。

现在我不知道的是,为什么旧​​的foreach循环在新的foreach循环中没有给出异常?

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));
        }
    }
}

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

因为每个循环都是基于迭代器的,所以你不能只是在迭代它时从列表中删除一个元素。 您甚至可以尝试显式使用迭代器并删除元素。

    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 
    }  

在迭代它时使用索引从列表中删除元素,肯定不会抛出任何异常,但是你需要特别注意它的长度被修改。甚至其他元素的索引也会因您的操作而受到干扰。所以,如果你照顾这个不是问题。

答案 2 :(得分:0)

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

public void java8Solution() {
    list.removeIf(person -> person.getPosition().equals(this.getPosition()));
}