遍历的同时修改一个 List 有几种方式?

面试回答

我们知道,在 foreach 的同时修改集合,会触发 fail-fast 机制,要避免 fail-fast 机制,有如下处理方案:

1.通过普通的 for 循环

    public void listRemove() {
        List<Student> students = this.getStudents();
        for (int i = 0; i < students.size(); i++) {
            if (students.get(i).getAge() % 3 == 0) {
                Student student = students.get(i);
                students.remove(student);
            }
        }
    }

2.使用迭代器循环

    public void listRemove() {
        List<Student> students = this.getStudents();
        Iterator<Student> stuIter=students.listIterator();
        while (stuIter.hasNext()) {
            Student student=stuIter.next();
            if (student.getAge() % 3 == 0) {
                stuIter.remove();
            }
        }
    }

3.将原来的 copy 一份副本,遍历原来的 list,然后删除 副本(fail-safe)

    public void copyRemove() {
        // 注意,这种方法的 equals 需要重写
        List<Student> students = this.getStudents();
        List<Student> studentsCopy=deepclone(students);
        Iterator<Student> stuIter=students.listIterator();
        for(Student stu:students){
            if(neelDel(stu)){
                studentsCopy.remove(stu);
            }
        }
    }

4.使用并发安全的集合类

    public void cowRemove() {
        List<Student> students=new CopyOnWriteArrayList<>(this.getStudents());
        for(Student stu:students){
            if(stu.getAge()%2==0){
                students.remove(stu);
            }
        }
    }

5.通过 Stream 的过滤方法,因为 Stream 每次处理后都会生成一个新的 Stream,不存在并发问题,所以 Stream 的 filter 也可以修改 list 集合

    public List<Student> streamRemove() {
        List<Student> students = this.getStudents();
        return students.stream()
                .filter(item -> item.getAge() % 2 != 0)
                .collect(Collectors.toList());
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

协享科技

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

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

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

打赏作者

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

抵扣说明:

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

余额充值