ArrayList<integer> list = new ArrayList<integer>(); list.add(2); list.add(2); list.add(3); list.add(1); list.add(2); System.out.println(list); for (int i=0; i<list.size(); i++){ if(list.get(i)<3) { list.remove(i); } } System.out.println(list);
原發問者想要將小於 3 的值全部移掉只剩下 3 這個元素,但是卻印出 [1 , 2],上面的的Sample Code 我有修改過,所以顯示為 [2,3,2] ,因為原程式在判斷條件小於3 的 if 後面多了分號 Orz。
Anyway, 回到原來的問題,當你刪除一個元素時 size 也會跟著縮小,但是 i 的值卻會遞增,在 for 迴圈最後面加入除錯訊息,就可以知道為何印出 [2, 3, 2]。下面是我在 for 迴圈中加入除錯訊息所印出的資料:
i = 0 : [2, 3, 1, 2] size:4
i = 1 : [2, 3, 1, 2] size:4
i = 2 : [2, 3, 2] size:3
要解決這個問題有下面三種方式
- 透過 Iterator
- 透過 for 迴圈反向檢查,可以在 ConcurrentModificationException for ArrayList 中查到方式。
- 透過 CopyOnWriteArrayList
透過 Iterator 方式如下:
Iterator<Integer> Allelement = list.iterator(); while (Allelement.hasNext()) { if (Allelement.next() < 3) { Allelement.remove(); // 刪除最後 Iterator 所回傳的值,也就是目前所指到值 } }透過 for 迴圈反向檢查:
for (int i = list.size() - 1; i >= 0; i--) { if(list.get(i) < 3){ list.remove(i); } }
透過 CopyOnWriteArrayList:
CopyOnWriteArrayList <Integer> list = new CopyOnWriteArrayList <Integer>(); list.add(2); list.add(2); list.add(3); list.add(1); list.add(2); for (Integer val : list) { if (val < 3) { list.remove(val); } }請注意,使用 foreach 去詢訪 ArrayList 時,你不可以在 foreach 中 執行 remove,如果執行了應該會出現 java.util.ConcurrentModificationException 的例外訊息。