ArrayList踩坑二:ArrayList循环删除

    ArrayList应该是在我们开发中最常用的集合,有时候我们业务需求,需要在循环中删除一个或者多个元素,我们怎样去在循环中删除ArrayList中的元素呢?

错误案例一:

public class ArrayListDeleteDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        for (String str : list) {
            list.remove(str);
        }
        System.out.println(list);
    }
}

    运行结果: 

    这里抛了ConcurrentModificationException, ConcurrentModificationException是基于java集合中的快速失败(fail-fast)机制产生的,在使用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了增删改,就会抛出该异常。快速失败机制使得java的集合类不能在多线程下并发修改,也不能在迭代过程中被修改。

错误案例二:

public class ArrayListDeleteDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        for (int i = 0; i < list.size(); i++) {
            list.remove(i);
        }
        System.out.println(list);
    }
}

    这个案例乍一看,好像没啥问题,那我们看看运行结果:

   通过运行结果可以看出,跟我们预期的不一样,没有删干净,是因为循环中删除会导致被删元素后续元素的索引发生变化,后续元素都会往前挪一位,所以会出现了这样的结果。

正确案例一:

public class ArrayListDeleteDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        for (int i = list.size() -1 ; i >=0; i--) {
            list.remove(i);
        }
        //或者以下方式也能达到同样的效果
        //for (int i = 0; i < list.size(); i++) {
        //    list.remove(i);
        //    i--;
        //}
        System.out.println(list);
    }
}

    上面的错误案例二是正序删的,会有索引挪位的问题,那我倒过来删不就可以解决嘛,每次删除最后那一个,就不会有索引挪位的问题了。

    运行结果:

    根据运行结果可以看出,正确的把元素删干净了。 

正确案例二:

public class ArrayListDeleteDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()){
            //如果不加这句代码,会有什么后果,大家想想
            iterator.next();

            iterator.remove();
        }
        System.out.println(list);
    }
}

    这里我们使用迭代器来循环删除,也是能正确删除数组里的元素。

    运行结果: 

正确案例三:

public class ArrayListDeleteDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");

        List<String> delList = new ArrayList<>();
        for (String str: list){
            if(str.equals("a") || str.equals("b")){
                delList.add(str);
            }
        }
        list.removeAll(delList);
        System.out.println(list);
    }
}

     这也是我们在项目开发中一种比较常用的删除方法,在循环里不删,记录下来需要被删的元素,待循环结束后再去统一删除。

运行结果: 

总结:

    本文给大家分享了一下循环删除的使用姿势,特别是正确案例二和正确案例三我比较推荐大家使用,但上述的几种方式中,都无法保证多线程安全,如果大家的业务需求是对线程安全有要求,就需要去加锁或者换线程安全的list集合。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值