ArrayList中的遍历删除

例如我们有下列数据,要求遍历列表并删除所有偶数。

List myList = new ArrayList<>(Arrays.toList(new Integer[]{2, 3, 5, 8, 10, 9}));

代码1:直接遍历列表并删除(错误)

初学者可能会直观地认为,我直接一个for循环遍历删除不就好了吗?但实际上这种做法是错误的。

static void remove1(List list) {
    for (int i = 0; i < list.size(); i++) {
        if (list.get(i) % 2 == 0) {
            list.remove(i);
        }
    }
}

使用上面的测试数据,结果为: [3, 5, 7, 10, 9],其中一个偶数 10 并没有被删除。

事实上,当删除列表中元素时,列表的 size() 会改变!当第一个 2 被删除时,此时 list.size() 已经从 6 变成了 5,而 i 只会一直向前跑,因此当 8 被删除时, list.size() 为 4,此时 i 已经变为 5,不再满足 i < list.size() 的循环条件,就会退出循环,后面的元素也不会再被处理。

代码2:控制循环变量的遍历(低效)

第二种做法是,不采用 for 循环,而是采用 while 循环 + 控制循环变量 i 的做法。

static void remove2(List list) {
    int i = 0;
    int j;
    while (i < list.size()) {
        if (list.get(i) % 2 == 0) {
            j = i--;
            // 此处存在 i < 0 的可能,所以要及时恢复 i 的位置
            if (i < 0) {
                i = 0;
            }
            list.remove(j); // 注意此处删除的是 j(也就是原来的 i)指向的元素
        } else {
            i++;
        }
    }
}

这里要对循环变量 i 进行控制,当删除一个元素时, i 并不能向前进一个位置而应该向后回退一个位置,从这个回退的位置开始重新向前走,才不至于遗漏本应被遍历到的元素。

代码3:使用迭代器(推荐)

一种更好的写法是使用迭代器,因为迭代器会自动判断列表中的每一个元素是否被遍历过。事实上,迭代器的实现和代码 2 很接近,但是可读性更好。

static void remove3(List list) {
    Iterator iterator = list.iterator();
    while (iterator.hasNext()) {
        Integer next = iterator.next();
        if (next % 2 == 0) {
            iterator.remove();
        }
    }
}

代码4:使用 removeIf() 方法

static void remove4(List list) {
    list.removeIf(new Predicate() {
        @Override
        public boolean test(Integer i) {
            return i % 2 == 0;
        }
    });
}

或者采用 lambda 表达式,更简洁:

list.removeIf(i -> i % 2 == 0);

以上就是对列表遍历删除的方法总结。如果条件比较简单,可以直接采用 removeIf() 方法,如果条件比较复杂,那么采用迭代器是一种比较好的方法。

Original: https://www.cnblogs.com/ryuasuka/p/15845660.html
Author: 飞鸟_Asuka
Title: ArrayList中的遍历删除

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/609188/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 系统架构的11条原则

    基本原则 原则一:价值为王 解析: 价值为王的另一种说法叫做YAGNI。YAGNI 是 You aren’t gonna need it 的缩写。该原则的基本含义就是,…

    Linux 2023年6月14日
    0124
  • VMware ESXi 7.0 Update 3c SLIC 2.6 & Unlocker (2022 U3 Refresh)

    提供标准版和 Dell (戴尔)、HPE (慧与)、Lenovo (联想)、Inspur (浪潮)、Cisco (思科) 定制版镜像 请访问原文链接:VMware ESXi 7.0…

    Linux 2023年5月27日
    099
  • 爱前端公开课学习笔记——JS02 字符串类型,布尔类型

    字符串是用引号包裹的,表示语言文字。 用双引号包裹的都是字符串 console.log(typeof 5); // number console.log(typeof "…

    Linux 2023年6月14日
    077
  • 渣画质视频秒变清晰,“达芬奇”工具集帮你自动搞定

    https://www.msra.cn/zh-cn/news/features/davinci 2022-06-23 | 作者:微软亚洲研究院 编者按:是否时常”考古&…

    Linux 2023年6月13日
    0187
  • 不自由的自由职业

    大家好,我是良许,前码农,现在自由职业者。 有关注我朋友圈的小伙伴都知道,就在上周,我刚刚结束了长达 35 天的「假期」。 此言一出,立刻掀起了评论区留言狂潮,大家纷纷问我,你特么…

    Linux 2023年6月14日
    088
  • K8S-kubeadm安装

    K8S-kubeadmin快速安装K8S集群 1.IP规划 节点 IP 组件 MASTER01(4C/6G,cpu核心数大于2) 192.168.80.20 docker、kube…

    Linux 2023年6月13日
    0108
  • linux命令之wget下载

    wget wget 是一个下载文件的工具。 格式 wget [&#x53C2;&#x6570;] [URL&#x5730;&#x5740;] 常用参…

    Linux 2023年5月27日
    089
  • c++ 11 是如何简化你的数据库访问接口的

    之前写过一篇文章专门分析了 c++ 模板编译过程中报的一个错误:《fatal error C1045: 编译器限制 : 链接规范嵌套太深 》,其中涉及到了 qtl —— 一个使用 …

    Linux 2023年6月6日
    0104
  • typesafe_cb

    callback 回调函数 什么是callback function 如图(来自维基百科),回调函数提供了一种服务,可以由用户决定使用怎么样的服务(登记回调函数)。回调函数机制,提…

    Linux 2023年6月8日
    0111
  • 我的第一个博客

    我就是想试一试 .阿西吧 段狗是傻逼,段狗请看右边的看板娘 posted @2020-06-22 18:56 xiao-c 阅读(17 ) 评论() 编辑 Original: ht…

    Linux 2023年6月7日
    0143
  • Spring中毒太深,离开了Spring,我居然连最基本的接口都不会写了¯_(ツ)_/¯

    前言 众所周知,Java必学的框架其中就是SSM,Spring已经融入了每个开发人员的生活,成为了不可或缺的一份子。 随着 Spring 的崛起以及其功能的完善,现在可能绝大部分项…

    Linux 2023年6月13日
    088
  • 快速掌握 Base 64 | Java JS 密码系列

    Java 密码系列 – Java 和 JS Base 64 Base 64 不属于密码技术,仅是编码方式。但由于在 Java、JavaScript、区块链等出现的频率较…

    Linux 2023年6月7日
    0102
  • Docker 安装 MySQL、Redis

    1 Docker 中安装 Redis 1.1 创建目录 在硬盘上创建 redis 的数据目录: mkdir -p /Users/yygnb/dockerMe/redis/data …

    Linux 2023年6月7日
    0109
  • Docker从入门到精通

    1 容器简介1.1 什么是 Linux 容器1.2 容器不就是虚拟化吗1.3 容器发展简史2 什么是 Docker?2.1 Docker 如何工作?2.2 Docker 技术是否与…

    Linux 2023年6月7日
    089
  • 利用numpy实现list降维

    python读取数据库得到的事一个类似二维数组的list,有时候需要降维操作,numpy提供一个很有用的函数,可以直接使用 import numpy as np a = np.ar…

    Linux 2023年6月14日
    0128
  • phpcmsv9 后台统计编辑发稿数量

    直切正题: 每个人,每个栏目,发稿数量统计 SELECT a.realname AS 姓名, c.catname AS 栏目名称, count(1) AS 发稿量FROM v9_n…

    Linux 2023年6月13日
    0100
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球