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>