如果在循环中删除列表中的元素

我们在在讨论这个问题之前,先考虑以下代码的输出结果:

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);

输出结果:

[b,d]

以上代码的目的是想遍历删除list中所有元素,但是结果却没有成功。

原因是忽略了一个关键的问题:
当一个元素被删除时,列表的大小缩小并且下标也会随之变化,所以当你想要在一个循环中用下标删除多个元素的时候,它并不会正常的生效。

也有些人知道以上代码的问题就由于数组下标变换引起的。所以我们试试使用增强for循环的形式:

ArrayList<String> list = new ArrayList<String>(Arrays.asList("a","b","c","d"));
for(String s:list){
    
    
    if(s.equals("a")){
    
    
        list.remove(s);
    }
}

运行以上代码会抛出ConcurrentModificationException异常
但是加一个break就不会了

ArrayList<String> list = new ArrayList<String>(Arrays.asList("a","b","c","d"));
for(String s:list){
    
    
    if(s.equals("a")){
    
    
        list.remove(s);
        break;
    }
}

最终找到原因,我们需要使用Iterator:

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();
    }
}

next()方法必须在调用remove()方法之前调用。如果在循环过程中先调用remove(),再调用next(),就会导致异常ConcurrentModificationException。

猜你喜欢

转载自blog.csdn.net/zhaozihao594/article/details/113055003