ArrayList 删除指定值

现在有这么一个需求,删除数组中值为1的项,这个问题看起来非常简单,可实际上非常容易出错,而且很有可能自己都没发现,一般我们是这么处理的:

初始化10万条数据:

for (int i = 0; i < 100000; i++) {
            list.add(i % 10);
        }

删除 =1 的项:

for (int i = 0; i < list.size(); i++) {
            if (list.get(i) == 1) {
                list.remove(i);
            }
        }

运行结果:

这里写图片描述
我们一看没问题啊,我们以为已经解决了,如果我们删除1和2的值,

for (int i = 0; i < list.size(); i++) {
            if (list.get(i) == 1 || list.get(i) == 2) {
                list.remove(i);
            }
        }

你会发现怎么指删除了10000条数据啊,怎么和只删除1的结果一样啊,你的第一反应是不是代码写错了,于是又看了看,没错啊,这个 时候我们就要好好分析下了:

数据集合:[0,1,2,3,4,5,6,7,8,9,0,1….]
第一步:i=0,list.get(i) =0,过。

第二步:i=1,list.get(i) =1,删除当前项,
此时的数据集合变为:[0,2,3,4,5,6,7,8,9,0,1….]
第三步:i=2,list.get(i) =3,就是这看好了,由于删除了一项导致列表发 生变化,使原数据的第三项跳过了。

到这里我们已经明白为什么出错了,找到了原因解决起来也就比较简单了我总结了几个解决方法:
1、递归方法,就是每次删除后重新开始:

private void delete1(){
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) == 1 || list.get(i) == 2) {
                list.remove(i);
                delete1();
            }
        }
    }


这种方法其实我不想介绍的,不过后来想想我们可以当成反面教材嘛,这种方法效率惨不忍睹,任何时候不到万不得已千万不要用递归。

2、根据出错的分析我们可以在删除时执行i–:

for (int i = 0; i < list.size(); i++) {
            if (list.get(i) == 1 || list.get(i) == 2) {
                list.remove(i);
                i--;
            }
        }

3、倒叙执行:

for (int i = list.size() - 1; i >= 0; i--) {
            if (list.get(i) == 1 || list.get(i) == 2) {
                list.remove(i);
            }
        }

4、使用Iterator

Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()) {
            int item = iterator.next();
            if (item == 1 || item == 2) {
                iterator.remove();
            }
        }


使用2、3、4都可以达到我们想要的效果,从10万条数据测试的效率来看都在800ms左右,不过我还是建议使用Iterator。

希望对大家有帮助,如果有什么问题评论留言,有更好的办法希望大家在评论分享下,我们共同进步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老孟Flutter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值