Java中集合迴圈刪除元素的問題
阿新 • • 發佈:2019-02-18
1、在一個迴圈中刪除一個列表中的元素
思考下面這一段在迴圈中刪除多個元素的的程式碼
Java程式碼
輸出結果是:
Java程式碼
在這個方法中有一個嚴重的錯誤。當一個元素被刪除時,列表的大小縮小並且下標變化,所以當你想要在一個迴圈中用下標刪除多個元素的時候,它並不會正常的生效。
你也許知道在迴圈中正確的刪除多個元素的方法是使用迭代,並且你知道java中的foreach迴圈看起來像一個迭代器,但實際上並不是。考慮一下下面的程式碼:
Java程式碼
它會丟擲一個ConcurrentModificationException異常。
相反下面的顯示正常:
Java程式碼
思考下面這一段在迴圈中刪除多個元素的的程式碼
Java程式碼
- ArrayList<String> list = new ArrayList<String>(Arrays.asList("a","b","c","d"));
- for(int i=0;i<list.size();i++){
- list.remove(i);
- }
- System.out.println(list);
輸出結果是:
Java程式碼
- [b,d]
在這個方法中有一個嚴重的錯誤。當一個元素被刪除時,列表的大小縮小並且下標變化,所以當你想要在一個迴圈中用下標刪除多個元素的時候,它並不會正常的生效。
你也許知道在迴圈中正確的刪除多個元素的方法是使用迭代,並且你知道java中的foreach迴圈看起來像一個迭代器,但實際上並不是。考慮一下下面的程式碼:
Java程式碼
- ArrayList<String> list =
- for(String s:list){
- if(s.equals("a")){
- list.remove(s);
- }
- }
它會丟擲一個ConcurrentModificationException異常。
相反下面的顯示正常:
Java程式碼
- ArrayList<String> list = new ArrayList<String>(Arrays.asList("a","b","c","d"));
- Iterator<String> iter = list.iterator();
- while(iter.hasNext()){
- String s = iter.next();
- if(s.equals("a")){
- iter.remove();
- }
- }
當size出現變化時,cursor並不一定能夠得到同步,除非這種變化是Iterator主動導致的。
從上面的程式碼可以看到當Iterator.remove方法導致ArrayList列表發生變化時,他會更新cursor來同步這一變化。但其他方式導致的 ArrayList變化,Iterator是無法感知的。ArrayList自然也不會主動通知Iterator們,那將是一個繁重的工作。Iterator到底還是做了努力:為了防止狀態不一致可能引發的無法設想的後果,Iterator會經常做checkForComodification檢查,以防有變。如果有變,則以異常丟擲,所以就出現了上面的異常。