java foreach循环删除报错

1、使用 foreach 进行删除数据时,出现错误:

  List<String> list = new ArrayList<String>();
        list.add("1");
        list.add("2");
        list.add("3");
        for (String temp : list) {
            if ("3".equals(temp)) {list.remove(temp);
            }
        }
        System.out.println(list.toString());

出现错误:

java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
    at java.util.ArrayList$Itr.next(ArrayList.java:831)

原因:

foreach 方式遍历元素的时候,是生成 iterator,然后使用 iterator 遍历。在生成 iterator 的时候,会保存一个 expectedModCount 参数,这个是生成 iterator 的时候 List 中修改元素的次数。如果你在遍历过程中删除元素,List 中 modCount 就会变化,如果这个 modCount 和 exceptedModCount 不一致,就会抛出异常。这个是为了安全的考虑。如果使用 iterator 遍历过程中,使用 List 修改了元素,可能会出现不正常的现象。如果使用 iterator 的 remove 方法则会正常,因为 iterator 的 remove 方法会在内部调用 List 的 remove 方法,但是会修改 excepedModCount 的值,因此会正常运行,如下代码所示:

    public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();
        </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
            ArrayList.</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.remove(lastRet);
            cursor </span>=<span style="color: rgba(0, 0, 0, 1)"> lastRet;
            lastRet </span>= -1<span style="color: rgba(0, 0, 0, 1)">;
            expectedModCount </span>=<span style="color: rgba(0, 0, 0, 1)"> modCount;
        } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (IndexOutOfBoundsException ex) {
            </span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ConcurrentModificationException();
        }
    }</span></pre>

 

2、正常删除代码如下:不使用 foreach

  List<String> list = new ArrayList<String>();
        list.add("1");
        list.add("2");
        list.add("3");
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()){
            if (iterator.next().equals("3")){iterator.remove();
            }
        }
    System.out.println(list.toString());</span></pre>