为什么对foreach方法进行并发修改而不是for for循环

时间:2017-08-01 13:31:49

标签: java concurrentmodification

 ArrayList<Integer> targets = new ArrayList<Integer>();
 targets.add(2);
 targets.add(2);

 for (Integer testInt : targets )
 {
       targets.add(1);
 }

我收到了concurrentModificationException,但是正常的for循环。我没有任何例外。 在正常的forloop中: -

for(int i=0;i<target.size();i++)
{
   System.out.println(target.get(i));
   target.add(22); //no exception
   target.remove(2) // no exception 
}

1 个答案:

答案 0 :(得分:3)

ForEach循环不会直接在您的集合上循环。它使用了你的集合的迭代器。你可以在集合实现中看到迭代器。

来自Arraylist source code

735 
736     public Iterator<E> More ...iterator() {
737         return new Itr();
738     }


An optimized version of AbstractList.Itr
742 
743     private class More ...Itr implements Iterator<E> {
744         int cursor;       // index of next element to return

你的foreach循环等于

for(Iterator<Integer> i = targets.iterator(); i.hasNext(); ) {
  Integer element = i.next();
  //To do
}

因此,如果您在此处执行任何操作,并且同时修改集合,则引擎盖下的迭代器会出现混淆并引发异常。

来自JLS

List<? extends Integer> l = ...
for (float i : l) ...

将被翻译为:

for (Iterator<Integer> #i = l.iterator(); #i.hasNext(); ) {
    float #i0 = (Integer)#i.next();
    ...