在循环内部删除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 }