首页 > 技术文章 > 循环删除指定文字或字符的方法注意事项

huanglp 2019-07-25 16:42 原文

错误的方法:

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还是处于第四个位置,不会跳到第三个位置。

 

推荐阅读