错误的方法:
public void filter(){
//List<String> list = new List<>();
List<String> list = new ArrayList<String>(Arrays.asList("111","222...","3333","444...","5555..."));
for (int i=0;i<list.size();i++){
String s = list.get(i);
System.out.println("ss"+i+"out"+s);
if (s.endsWith("...")){
list.remove(i);
}
}
}
输出结果为:
这种方法或许看着感觉没什么问题,但上面这种方式会抛出java.lang.IndexOutOfBoundsException
异常。这种方式的问题在于,删除某个元素后,list的大小发生了变化,而你的索引也在变化。假设被遍历list中共有10个元素,当删除了第3个元素后,第4个元素就变成了第3个元素了,第5个就变成了第4个了,但是程序下一步循环到的索引是第4个,这时候取到的就是原本的第5个元素了。这样当迭代到最后一个的时候就会抛异常。因此,这种方式可以用在删除特定的一个元素时使用,但不适合循环删除多个元素时使用。
改进方法: https://blog.csdn.net/GarfieldEr007/article/details/80260818
for(int i=0,len=list.size();i< len;i++){
if(list.get(i).equals("del")){
list.remove(i);
--len;//减少一个
//此时要注意,因为list会动态变化不像数组会占位,所以当前索引应该后退一位
--i;
}
}
个人觉得这时候使用迭代器,就比较方便了很多
public void filter(){
//List<String> list = new List<>();
List<String> list = new ArrayList<String>(Arrays.asList("111","222...","3333","444...","5555..."));
Iterator<String> it = list.iterator();
while(it.hasNext()){
String x = it.next();
System.out.println("out"+x);
if(x.endsWith("...")){
it.remove();
}
}
System.out.println(list.toString());
System.out.println("=================");
}
输出结果为
迭代器iterator的remove()方法不仅会删除元素,还会维护一个标志,用来记录目前是不是可删除状态。例如,你不能连续两次调用它的remove()方法,调用之前至少有一次next()方法的调用。但是要注意的是:list.remove()只是删除元素,可是不会改变原有元素的位置。比如有 0 1 2 3 4 5这六个元素,我删除掉3这个元素,则4还是处于第四个位置,不会跳到第三个位置。