java在foreach裡面刪除元素分析
阿新 • • 發佈:2019-01-08
比較好的刪除集合中元素的做法。
方法(1):
public static void main(String[] args) { List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(2); list.add(3); list.add(1); list.add(5); Iterator<Integer> iterator = list.iterator(); while (iterator.hasNext()) { Integer value = iterator.next(); if (value == 1) { iterator.remove(); } } System.out.println(list); }
方法(2):
可以看到這裡不呼叫hasNext()也是可以的
也可以知道iterator.remove()方法裡面肯定改變了expectedModCount,使其等於modCount的值,然後再次呼叫iterator.next()方法的時候不會報錯,看看ArrayList裡面的原始碼public static void main(String[] args) { List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(2); list.add(3); list.add(1); list.add(5); Iterator<Integer> iterator = list.iterator(); int len = list.size(); int index = 0; while (len > 0 && index <= len) { Integer value = iterator.next(); if (value == 1) { iterator.remove(); } index++; len = list.size(); } System.out.println(list); }
public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } }
再看看如下程式碼:
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(1);
list.add(5);
Iterator<Integer> iterator = list.iterator();
list.add(1234);
while (iterator.hasNext()) {
Integer value = iterator.next();
if (value == 1) {
iterator.remove();
}
}
System.out.println(list);
}
還是會報這個錯誤,Exception in thread "main" java.util.ConcurrentModificationException,
現在比較好理解了,初始化的時候iterator裡面expectedModCount值已經為5了,然後執行list.add(1234),modCnt為6,但是expectedModCount還是為5。
所以出現錯誤了。
總結:在iterator執行的程式碼段裡面,最好不要混合集合的add和remove操作。集合的add和remove操作,應該在iterator執行的程式碼端之前或之後。