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 的例外訊息。
沒有留言:
張貼留言