记:java list遍历删除元素引发的bug

bug场景:

list遍历删除元素
昨天,项目需求中要对一个list进行遍历删除满足条件的元素,然而用for循环正序遍历时,不能完全删除,从而引发bug,观察后记录下来


问题描述:

提示:list删除不彻底

测试对象

class Patient {
    private String name;
    private String outdate;
    @Override
    public String toString() {
        return "Yizhu{" +
                "name='" + name + '\'' +
                ", outdate='" + outdate + '\'' +
                '}';
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getOutdate() {
        return outdate;
    }
    public void setOutdate(String outdate) {
        this.outdate = outdate;
    }
    public Patient(String name, String outdate) {
        this.name = name;
        this.outdate = outdate;
    }
}

原代码(错误):

//向list添加数据
ArrayList<Patient>_patientInfos=new ArrayList();
        _patientInfos.add(new Patient("1","2021-01-01"));
        _patientInfos.add(new Patient("2",""));
        _patientInfos.add(new Patient("3",""));
        _patientInfos.add(new Patient("4","2021-01-01"));
        _patientInfos.add(new Patient("5","2021-01-01"));
//一般正序遍历
        for(int i=0;i<=_patientInfos.size()-1;i++){
            if (_patientInfos.get(i).getOutdate()!=null ){
                _patientInfos.remove(_patientInfos.get(i));
            }
        }
        System.out.println(_patientInfos);

输出结果


原因分析:

提示:list漏删元素
在遍历时满足条件则remove掉此元素,list长度变化,for循环中i值将继续往后累计
举个栗子:如果下标i=0满足如图条件,list将删除掉下标为0的元素,此时list.size()=4,继续for循环,下一步i=1,此时原list中的第二个元素将变为新list的第一个元素,将判断新list中第二个元素是否满足条件,漏掉新list中第一个元素,and so on


解决方案:

发现这个问题的时候还挺严重的,被领导好多人喷,都是自己学艺不精,思索不周,赶紧爬起来修复排查,(慌得一批)

排查后发现有几种解决方案
迭代器遍历删除

 //正确 可删除多个
        Iterator<Patient> iterator = _patientInfos.iterator();
        while (iterator.hasNext()) {
            Patient patient = iterator.next();
            if (patient.getOutdate() != null) {
                iterator.remove();//使用迭代器的删除方法删除
            }
            System.out.println(_patientInfos);
        }

输出结果
在这里插入图片描述

倒序删除
在倒序时,如果满足条件则删除,下标前移,即使list长度变化也不会有影响,满足需求

for(int i=_patientInfos.size()-1;i>=0;i--){
        if (_patientInfos.get(i).getOutdate()!=null ){
            _patientInfos.remove(_patientInfos.get(i));
         }
    }

输出结果
在这里插入图片描述
其他方法:
可以另外新建list,for中满足条件的放入新list中
遍历结束后,list.removeAll(新list);移除掉新list,效率较低

                                                                                                     学无止境
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值