在循環內部刪除List中的一個元素,一不小心就會進入坑了。
首先看下如下代碼,在迭代期間刪除元素:
1 List<String> list=new ArrayList<String>(Arrays.asList("a","b","c","d")); 2 for (int i=0;i<list.size();i++){ 3 list.remove(i); 4 } 5
6 System.out.println(list)
打印結果:[b,d]
對的,打印的結果就是[b,d],怎么跟設想的結果[]不一樣呢。
原因是:用上面這種情況,當一個元素被刪除的時候,list大小會減小,然后原先索引指向了其它元素。所以如果你想在循環里通過索引來刪除多個元素,將不會正確工作。
你也許知道使用迭代器是在循環里刪除元素的正確方式,或許你也知道foreach循環跟迭代器很類似,但事實情況卻不是這樣的,如下代碼:
1 List<String> list=new ArrayList<String>(Arrays.asList("a","b","c","d")); 2 for(String s:list){ 3 if (s.equals("a")){ 4 list.remove(s); 5 } 6
7 }
運行結果是將拋出ConcurrentModificationException異常。因為next()方法需要在remove()方法之前被調用,在foreach循環里,編譯器會在刪除元素操作后調用next()方法,這導致了ConcurrentModificationException異常。
所以,正確的代碼是采用直接的迭代器去刪除,代碼如下:
1 List<String> list=new ArrayList<String>(Arrays.asList("a","b","c","d")); 2 Iterator<String> iter=list.iterator(); 3 while (iter.hasNext()){ 4 String s=iter.next(); 5 if(s.equals("a")){ 6 iter.remove(); 7 } 8 }