这个问题看起来很基础,但还是有很多人在这上面犯错,今天就做个记录,以备查阅。
比如要删除符合条件的某个特定元素,菜鸟往往会这么写:
List list = new ArrayList();
for (int i = 0; i < 10; i++) {
list.add((i+1));
}
for (int i = 0; i < list.size(); i++) {
if((list.get(i) %2==0 ){ //删除索引为奇数的元素
list.remove(i);
}
}
但结果却事与愿违,抛异常了,为什么呢?因为ArrayList的长度是可变的,也就是说for循环的次数也是变化的,于是你可能会想到,用变量把list的长度保存下来,每移除一个元素,list长度减1.听起来貌似可以,结果菜鸟又把代码改成:
int count = list.size();
for (int i = 0; i < count; i++) {
if((list.get(i) %2==0 ){ //删除索引为奇数的元素
list.remove(i);
count--;
}
}
结果呢,还是不对,元素是有删除,但并不是我们期望的那样,为什么呢?因为删除一个元素后后面的元素都会整体前移一位,所以当list删除一个元素后索引++,就会漏掉刚刚删除元素后紧挨着的那个元素,所以这时候索引应该不变,只有这样才能保证每个元素都能遍历到。
int count = list.size();
for (int i = 0; i < count; i++) {
if(set.contains(list.get(i))){
list.remove(i);
count--;
i--;
}
}当然还有一种方法,就是先遍历list找出所有符合条件需要删除的元素,保存到另一个list或set集合中,然后list调用removeAll()删除集合中包含的所有元素。