Java中 普通for循环, 增强for循环( foreach) List中增删改查的注意事项

文章目录

  • 俩种循环
  • 遍历
  • 增加
  • 删除
    • 1 根据index删除
    • 2 根据对象删除
  • 修改

俩种循环

Java中 普通for循环, 增强for循环( foreach) 俩种List的遍历方式有何异同,性能差异?

普通for循环(使用索引遍历):

for (int i = 0; i < list.size(); i++) {  
    Object item = list.get(i);  
    // 处理item  
}

这是最基本的遍历方式,它使用索引来访问列表中的每一个元素。

增强for循环(也称为“foreach”循环):

for (Object item : list) {  
    // 处理item  
}

这种循环在Java 5中被引入,作为对集合遍历的语法糖。在内部,它仍然使用Iterator,但语法更为简洁。很多开发者也称之为“foreach”循环,但实际上在Java中并没有名为“foreach”的关键字;这是C#中的一个关键字。在Java中,这只是增强for循环的一种常见称呼。

异同点:

普通for循环:

需要显式地通过索引来访问元素。
可以方便地访问和修改当前索引位置的元素。
对于List的随机访问操作,性能是高效的,因为ArrayList等基于数组的列表支持快速的随机访问。

增强for循环:

语法简洁,不需要关心索引。
只能访问元素,不能方便地修改元素(除非元素是可变的对象,并且你修改了对象的内部状态)。
在内部,它使用Iterator,所以对于不支持快速随机访问的数据结构(如LinkedList),它的性能可能更优。
性能差异:

对于ArrayList等基于数组的列表:普通for循环通常会比增强for循环稍微快一点,因为它直接通过索引访问元素,避免了Iterator的开销。但这种差异在大多数情况下是微不足道的,除非列表非常大或者这段代码是性能瓶颈。
对于LinkedList等不支持快速随机访问的列表:增强for循环可能会更有优势,因为它内部使用Iterator,这与LinkedList的迭代访问方式相匹配。

遍历

ArrayList 情况下,普通for循环遍历就是最基础的for循环,而foreach底层是使用迭代器。

增加

删除

1 根据index删除

 List<String> list = new ArrayList<>(4);
        list.add("a");
        list.add("ab");
        list.add("abc");
        list.add("abcd");
 //错误方式 根据下标remove  数组形式 普通for循环
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).contains("a")) {
                list.remove(i);
            }
        }

[ab, abcd]

读者可能回想,怎么不是空的list呢?不妨让我们看下remove这个方法。(这个是ArrayList 里面的实现)

  public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);

        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }

其中

 System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);

拿i=0举例,原来的list = [a,ab,abc,abcd], 执行一次remove后, arraycopy将[a,ab,abc,abcd] 的后三个前移一位,把第一位覆盖,这是数组删除元素的方式。这样一来,原list就变成[ab,abc,abcd],第二次循环的时候i=1,此时list.get(1) = abc,直接跳过了ab,所以最后没有达到我们预期的空[].

正确的做法是使用迭代器

//正确方式 迭代器
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            if (iterator.next().contains("a")) {
                // 删除元素
                iterator.remove();
            }
        }

2 根据对象删除

//根据对象删除
        List<String> list2 = new ArrayList<>();
        list2.add("111");
        list2.add("222");
        list2.add("222");
        list2.add("333");

正确 普通for循环

//
        for (int i = 0; i <list2.size(); i++) {
            list2.remove("222");
        }

错误,增强for循环 抛异常

  //
        for (String s : list2) {
            list2.remove("222");
        }

原因:
迭代器内部的每次遍历都会记录List内部的modcount当做预期值,然后在每次循环中用预期值与List的成员变量modCount作比较,但是普通list.remove调用的是List的remove,这时modcount++,但是iterator内记录的预期值并没有变化,所以会报错。

如果想要删除元素的话需要使用迭代器内部的remove方法。

修改

foreach不可以删除/修改集合元素,而for可以

foreach和for都可以修改元素(对象)里面的属性

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/780727.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Google Java Style Guide深度解读:打造优雅的代码艺术

在软件工程的世界里&#xff0c;代码不仅仅是实现功能的工具&#xff0c;它也是团队之间沟通的桥梁&#xff0c;是软件质量和可维护性的直接反映。Google Java Style Guide作为一套广受认可的编码规范&#xff0c;不仅定义了代码的书写规则&#xff0c;更深刻地影响着Java开发者…

绿色金融相关数据合集(2007-2024年 具体看数据类型)

数据类型&#xff1a; 1.绿色债券数据&#xff1a;2014-2023 2.绿色信贷相关数据&#xff1a;2007-2022 3.全国各省及地级市绿色金融指数&#xff1a;1990-2022 4.碳排放权交易明细数据&#xff1a;2013-2024 5.绿色金融试点DID数据&#xff1a;2010-2023 数据来源&#…

python操作SQLite3数据库进行增删改查

python操作SQLite3数据库进行增删改查 1、创建SQLite3数据库 可以通过Navicat图形化软件来创建: 2、创建表 利用Navicat图形化软件来创建: 存储在 SQLite 数据库中的每个值(或是由数据库引擎所操作的值)都有一个以下的存储类型: NULL. 值是空值。 INTEGER. 值是有符…

Linux—网络设置

目录 一、ifconfig——查看网络配置 1、查看网络接口信息 1.1、查看所有网络接口 1.2、查看具体的网络接口 2、修改网络配置 3、添加网络接口 4、禁用/激活网卡 二、hostname——查看主机名称 1、查看主机名称 2、临时修改主机名称 3、永久修改主机名称 4、查看本…

【python】pyqt5大学生成绩信息管理系统-图形界面(源码+报告)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

基于支持向量机、孤立森林和LSTM自编码器的机械状态异常检测(MATLAB R2021B)

异常检测通常是根据已有的观测数据建立正常行为模型&#xff0c;从而将不同机制下产生的远离正常行为的数据划分为异常类&#xff0c;进而实现对异常状态的检测。常用的异常检测方法主要有&#xff1a;统计方法、信息度量方法、谱映射方法、聚类方法、近邻方法和分类方法等。 …

飞书 API 2-4:如何使用 API 将数据写入数据表

一、引入 上一篇创建好数据表之后&#xff0c;接下来就是写入数据和对数据的处理。 本文主要探讨数据的插入、更新和删除操作。所有的操作都是基于上一篇&#xff08;飞书 API 2-4&#xff09;创建的数据表进行操作。上面最终的数据表只有 2 个字段&#xff1a;序号和邮箱。序…

巴图自动化PN转Modbus RTU协议转换网关模块快速配置

工业领域中常用的通讯协议有&#xff1a;Profinet协议&#xff0c;Modbus协议&#xff0c;ModbusTCP协议&#xff0c;Profibus协议&#xff0c;Profibus DP协议&#xff0c;EtherCAT协议&#xff0c;EtherNET协议&#xff0c;CAN&#xff0c;CanOpen等&#xff0c;它们在自动化…

kubeadm快速部署k8s集群

文章目录 Kubernetes简介1、k8s集群环境2、linux实验环境初始化【所有节点】3、安装docker容器引擎【所有节点】4、安装cri-dockerd【所有节点】5、安装 kubeadm、kubelet、kubectl【所有节点】6、部署 k8s master 节点【master节点】7、加入k8s Node 节点【node节点】8、部署容…

【链表】【双指针】1、合并两个有序链表+2、分隔链表+3、删除链表的倒数第N个结点+4、链表的中间结点+5、合并两个链表

3道中等2道简单 数组和字符串打算告一段落&#xff0c;正好最近做的几乎都是双指针&#xff0c;所以今天做链表&#xff01; 1、合并两个有序链表&#xff08;难度&#xff1a;简单&#xff09; 该题对应力扣网址 AC代码 思路简单 /*** Definition for singly-linked list.…

昇思25天学习打卡营第12天|简单的深度学习ResNet50图像分类 - 构建ResNet50网络

ResNet主要解决深度卷积网络在深度加深时候的“退化”问题。在一般的卷积神经网络中&#xff0c;增大网络深度后带来的第一个问题就是梯度消失、爆炸&#xff0c;这个问题Szegedy提出BN层后被顺利解决。BN层能对各层的输出做归一化&#xff0c;这样梯度在反向层层传递后仍能保持…

P1392 取数

传送门&#xff1a;取数 如若你看完题解后&#xff0c;仍有问题&#xff0c;欢迎评论 首先说一下 我首先想到的思路 &#xff08; 20%通过率 &#xff09;&#xff1a;通过dfs , 将所有的情况放入priority_queue中&#xff08;greater<int>&#xff09;&#xff0c;维持…

计算两种人像之间的相似度

通过调研&#xff0c;目前存在几种能够计算两个人脸相似度的方法&#xff1a; 1.使用结构相似性计算人脸之间的相似度 结构准确性&#xff1a;生成的图片是否保留了原图足够多细节。 &#xff08;1&#xff09;结构准确性衡量指标&#xff1a;SSIM/MMSSIM SSIM&#xff08;结构…

纯前端低代码开发脚手架 - daelui/molecule

daelui/molecule低代码开发脚手架&#xff1a;分子组件开发、预览、打包 页面代码示例、大屏代码示例预览 可开发页面组件 可开发大屏组件 项目git地址&#xff1a;https://gitee.com/daelui/molecule 在线预览&#xff1a;http://www.daelui.com/daelui/molecule/app/index.…

STM32第十六课:WiFi模块的配置及应用

文章目录 需求一、WiFi模块概要二、配置流程1.配置通信串口&#xff0c;引脚和中断2.AT指令3.发送逻辑编写 三、需求实现代码总结 需求 完成WiFi模块的配置,使其最终能和服务器相互发送消息。 一、WiFi模块概要 本次使用的WiFi模块为ESP-12F模块&#xff08;安信可&#xf…

聚类分析方法(一)

目录 一、聚类分析原理&#xff08;一&#xff09;聚类分析概述&#xff08;二&#xff09;聚类的数学定义&#xff08;三&#xff09;簇的常见类型&#xff08;四&#xff09;聚类框架及性能要求&#xff08;五&#xff09;簇的距离 二、划分聚类算法&#xff08;一&#xff0…

车载测试之-CANoe创建仿真工程

在现代汽车工业中&#xff0c;车载测试是确保车辆电子系统可靠性和功能性的关键环节。而使用CANoe创建仿真工程&#xff0c;不仅能够模拟真实的车辆环境&#xff0c;还能大大提升测试效率和准确性。那么&#xff0c;CANoe是如何实现这些的呢&#xff1f; 车载测试中&#xff0…

PXIe-7976【K410T】

起售价 RMB 152,880.00 块RAM(BRAM): 28620 kbit 动态RAM(DRAM): 2 GB FPGA: Kintex-7 410T PXI背板链路: PCI-Express Gen2 x 8 FPGA片: 63550 DSP片: 1540

敏感词匹配DFA算法

算法简介与场景介绍 DFA算法&#xff0c;中文全称为确定性有穷自动机。它的基本思想是构建一个有穷自动机&#xff0c;当用户输入文本时&#xff0c;通过自动机的状态转换来快速匹配敏感词。具体特征是&#xff0c;有一个有效状态的集合和一些从一个状态通向另一个状态的边&am…

并发处理 优先图和多重图

优先图(Precedence Graph)视图可串性多重图(Polygraph) 优先图(Precedence Graph) 优先图用于冲突可串性的判断。 优先图结构&#xff1a; 结点 (Node)&#xff1a;事务&#xff1b;有向边 (Arc): Ti → Tj &#xff0c;满足 Ti <s Tj&#xff1b; 存在Ti中的操作A1和Tj…