Iterator源码解析及和for-each循环

Java ArrayList遍历修改代码实例解析 用for-each 边遍历ArrayList 边修改时: public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("aa"); list.add("bb"); list.add("cc"); list.add("dd"); System.out.println(list); for (String 阅读详情

在使用foreach循环遍历集合的过程中,如果集合被修改了,会抛出ConcurrentModificationException异常。

以这段代码为例子:

public class SynProblem {

	List<Widget> widgetList = Collections.synchronizedList(new ArrayList<>());
	{
		widgetList.add(new Widget(1));
		widgetList.add(new Widget(2));
		widgetList.add(new Widget(3));
	}

	public void test() {
		for (Widget w : widgetList) {
			doSomethings(w);
		}
	}

	private void doSomethings(Widget w) {
		System.out.println(w);
	}

	public static void main(String[] args) {
		SynProblem s = new SynProblem();
		s.test();
	}
}

使用javap反编译一下,可以看到在test方法中,for循环调用了iterator接口的方法

问题来了,foreach循环底层也是调用了iterator的方法,为什么在foreach循环add/remove集合元素,可能会抛出 ConcurrentModificationException 异常,但是使用iterator来remove 集合元素却不会呢?

下面以ArrayList为例:

调用ArrayList.iterator()返回的是ListItr,这是ArrayList的内部类,实现了Iterator接口

private class Itr implements Iterator<E> {
        int cursor;       //下一个返回元素索引
        int lastRet = -1; //最后一个返回元素索引,如果被remove该索引会被重置为-1
        int expectedModCount = modCount;//期待修改次数(可被视为 Itr内部记录的集合结构变化次数)

        Itr() {}

        public boolean hasNext() {
            return cursor != size;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();//1.
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.remove(lastRet);//调用集合的删除操作,modCount+1
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;//重新给expectedModCount赋值
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)//如果期待修改次数与实际修改次数不同,则抛出异常
                throw new ConcurrentModificationException();
        }
    }

而ArrayList的add方法,也会进行modCount ++

可以看到的是在foreach循环会调用next()方法,next方法会调用checkForComodification()来检查modCount 是否等于expectedModCount。要注意的是如果在for循环中直接使用add或者remove操作,是不会有下面这一步的。也就是说此时modCount != expectedModCount。抛出异常。这是java的 fail-fast 策略,用来防止多线程并发修改集合时,保证数据的一致性。

 

Iterator和Iterable的区别以及使用 Iterator和Iterable的区别以及使用 1、什么是迭代器 迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。迭代器修改了常规指针的接口,所谓迭代器是一种概念上的抽象:那些行为上像迭代器的东西都可以叫做迭代器。然而迭代器有很多不同的能力,它可以把抽象容器和通用算法有机的统一起来 Iterable,该接口包含一个能够产... 阅读详情

相关推荐

Java源码解析:ArrayList 和 Iterator 使用上的不同

文章目录1. 前言2. iterator 对象是什么类型? 1. 前言 ArrayList 是最常用的 List 类型,它提供了非常便捷的方法对数据进行增删改查,例如:add、remove、get、contains 等等。但是,实际应用中,我们经常需要在 for 循环判断数据,然后删除数据,ArrayList 在这方面的操作上是非常不方便的。下面我们看几个例子: 案例一: 在循环 for (String s : list) 进行删除数据: public class MyList { public s

qq_28834355的博客 374

Checkmarx快速入门指南

了解checkmarx的使用

qq_59611876的博客 6305

Java源码分析:深入探讨Iterator模式

Java源码分析:深入探讨Iterator模式

各个工具的使用

Alerta (https://alerta.io/) 该开源工具可将多个来源的信息整合去重,提供快速可视化功能。Alerta与Prometheus、Riemann、Nagios、Cloudwatch及其他监视/管理服务集成,开发人员可通过API按需定制Alerta。 2.ContrastAssess (https://www.contrastsecurity.com/interactive-application-security-testing-iast) 作为一款互动应用安全测试(IA

m0_64144988的博客 847

Iterator详解

java中迭代器的使用!文档详解,Android手机源码

【5G NB-IoT NTN】3GPP R17 NB-IoT NTN介绍_nbiot ntn

你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!” />你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!更多资料点击此处获qu!!

2401_83703866的博客 3165

工作中遇到的Fortify和Checkmarkx问题

Fortify和checkmarx工作中的问题

qq_42199464的博客 5568

保姆级教程:在RK3588开发板上驱动多路MIPI摄像头(从VICAP配置到ISP调优)

本文详细介绍了在RK3588开发板上驱动多路MIPI摄像头的完整流程,从VICAP配置到ISP调优的全方位解析。通过硬件架构分析、开发环境搭建、设备树配置、V4L2数据采集以及ISP图像调优等步骤,帮助开发者高效实现多路摄像头驱动,适用于工业检测和智能安防等领域。

weixin_42552315的博客 389

JDK源码解析---ArrayList分析

转载自:http://blog.youkuaiyun.com/tanggao1314/ 花了两个晚上的时间研究了一下ArrayList的源码,   ArrayList 继承自AbstractList 并且实现了List, RandomAccess, Cloneable, Serializable  通过实现这三个接口 就具备了他们的功能  RandomAccess 用来表明其支持快速(通常是固定时

Happy_wu的专栏 906

嵌入式硬件实战:RC、LC与RL滤波电路的设计与选型指南

本文深入探讨了嵌入式系统中RC、LC与RL滤波电路的设计与选型策略。通过生活化比喻和实战案例,详细解析了三种滤波电路的工作原理、应用场景及工程注意事项,帮助工程师根据电流大小、频率特征和成本预算选择最优方案,提升嵌入式硬件设计的稳定性和抗干扰能力。

kiwi8的博客 284

SRC漏洞挖掘实战:从攻击面管理到业务逻辑漏洞的精准狩猎

在网络安全领域,漏洞挖掘是识别和利用软件系统中安全弱点的核心实践。其基本原理在于通过系统化的方法,识别和评估一个应用或系统的攻击面,并从中定位安全防护的薄弱环节。这项技术的价值在于能够主动发现潜在风险,防患于未然,对于保障企业数字资产安全至关重要。典型的应用场景包括对Web应用、移动端API以及各类在线业务系统的安全性评估。在实际的漏洞挖掘,尤其是针对安全应急响应中心(SRC)的实战中,高效的策略往往聚焦于**边缘资产**的发现与利用,以及对**业务逻辑漏洞**的模式化测试。掌握这些经过验证的思路,能帮助安

babing2770的博客 414

浅析Java中的Iterator

Iterator java.util.Iterator接口:迭代器(对集合进行遍历),常用方法: boolean hasNext():判断集合中是否还有没有下一个元素,有则返回true,否则返回false E next():返回迭代的下一个元素 Iterator是一个接口,如果要使用它需使用Iterator接口的实现类对象,Colleantion接口中有一个iterator()方法用于返回迭代...

Forlogenの解忧杂货铺 467

在树莓派5(8G版)上运行Ollama + LLM

直接上结论,Ollama在树莓派上能安装,且本身运行起来毫无压力,但具体到大语言模型,Deepseek似乎不总是最佳选择。

ki1381的专栏 1651

Java使用for和迭代器Iterator中remove比较

1. Iterator介绍   对于java中的集合类(Collection),可以使用迭代器Iterator对集合中的元素进行遍历。迭代器是一种设计模式,它可以在不暴露集合中元素的情况下而去遍历集合中的所有元素。   Iterator为一个接口,只定义了三个方法,hasNext(),next(),和remove()。Collection接口继承Iterable接口,提供了一个iterator()方法,使得Collection子类通过iterator()方法获取Collection内部实现的Iterator

HachiLin的博客 799

STM32实战:如何用GPS信号同时同步海康摄像头和Livox Mid-360雷达(附完整接线图)

本文详细介绍了如何利用STM32实现GPS信号分频,同步海康摄像头和Livox Mid-360雷达的时间同步方案。通过硬件架构设计、STM32信号处理核心实现及设备接口规范,解决了多传感器数据融合中的时间对齐难题,适用于自动驾驶和机器人导航领域。

weixin_29182481的博客 596

硬件工程师笔记——运算放大电路Multisim电路仿真实验汇总

本文系统介绍了运算放大电路的基础知识及其应用。主要内容包括:1)运算放大器的基本结构、理想特性及分析方法(虚短、虚断、叠加定理);2)比例运算电路(同向、反向、差分)的工作原理与仿真分析;3)求和运算、加减运算电路的实现方法;4)积分、微分、指数和对数运算电路的基本原理;5)过零电压比较器的功能特点。通过理论分析和仿真实验,详细阐述了各类运算放大电路的输入输出特性、相位关系和增益计算,为硬件工程师提供了实用的电路设计参考。

XU157303764的博客 2479

Java集合迭代器:从Iterable到Iterator,揭秘遍历背后的设计哲学(通俗图解)

本文深入解析Java集合框架中Iterable与Iterator的设计哲学,通过通俗图解和源码分析,揭示两者在集合遍历中的分工与协作。从Iterable接口的三重身份到Iterator的四大核心能力,详细讲解安全遍历、元素删除等实用技巧,帮助开发者掌握Java集合迭代的最佳实践。

benben 409

高数15种常见特殊曲线:星形线、心形线、摆线、对数螺线、双曲螺线、阿基米德螺线、伯努利双纽线、三叶玫瑰线、四叶玫瑰线、六叶玫瑰线、三次抛物线、半立方抛物线、箕舌线、蔓叶线、笛卡儿叶形线、概率曲线

4.1 对数螺线(等角螺线、生长螺线)三叶玫瑰线、四叶玫瑰线、六叶玫瑰线。​7.2 半立方抛物线(尼尔曲线)10.笛卡儿叶形线(茉莉花瓣曲线)常考选择题、填空题,大题也涉及。​4.2 双曲螺线(倒数螺线)11.阿基米德螺线(等速螺线)3.摆线(圆滚线、旋轮线)5.双纽线(伯努利双纽线)1.星形线(四尖瓣线)2.心形线(心脏线)..................

刘鑫磊 1万+

ArrayList循环遍历并删除元素的常见陷阱

在工作和学习中,经常碰到删除ArrayList里面的某个元素,看似一个很简单的问题,却很容易出bug。不妨把这个问题当做一道面试题目,我想一定能难道不少的人。今天就给大家说一下在ArrayList循环遍历并删除元素的问题。首先请看下面的例子: 复制代码 import java.util.ArrayList; public class ArrayListRemove {   publicstaticvoidmain(String[]args)   {     ArrayListlist=newArrayLis

qq_44428824的博客 204

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

java基础篇(4)加强型for循环与Iterator

引言 从JDK1.5起,增加了加强型的for循环语法,也被称为 “for-Each 循环”。加强型循环在操作数组与集合方面增加了很大的方便性。那么,加强型for循环是怎么解析的呢?同时,这是不是意味着基本for循环就会被取代呢? 语法: for(var item:items){//var 代表各钟类型 //相关操作 } 一、数组中的 for-Each 循环 我们先来看一下数组中的 for...

cowbin2012的专栏 1万+

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

吃透Java集合系列一:Iterable和Iterator

前言: 作为吃透Java集合的开篇,我们从集合的最顶层接口(Iterable)撸起,通过本篇我们要明白三个问题: 1、什么是Iterable 2、什么是Iterator 3、Iterable和Iterator有什么关系 一:什么是Iterable JDK描述:实现此接口允许对象成为“ for-each循环”语句的目标。 那么什么是“ for-each循环”:“ for-each循环”是Java提供...

吃透Java 2013

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

JDK源码解析之java.util.Iterator和java.lang.Iterable

在Java中,我们可以对List集合进行如下几种方式的遍历:第一种就是普通的for循环,第二种为迭代器遍历,第三种是for each循环。后面两种方式涉及到Java中的iterator和iterable对象,接下来我们通过源码来看看这两个对象的区别以及如何在自定义类中实现for each循环。 一、Java.util.Iterator Java.util.Iterator 接口描述的是以统一的方式对各种集合元素进行遍历 / 迭代的工具,也称“迭代器”。 迭代器( Iterator )模式,又叫做游标(.

栗筝i的博客 4211

简单说明:ArrayList 在 For 循环中进行删除而产生异常的原因

经常会有人这么对 list 进行遍历,错而不自知。 示例代码如下: public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("aaa"); list.add("bbb"); list.add("ccc"); list.add("ddd"); for (String str : list) { if

桥边驿语人的博客 690

集合中的 for-Each循环

 数组的加强型的for-Each循环很简单,我们再来看一下集合中的for-Each 循环又是怎么样的。我们都知道集合中的遍历都是通过迭代(iterator)完成的。也许有人说,也可以按照下面的方式来遍历集合,不一定非要使用迭代: 1 List<String> list = new LinkedList<String>(); 2 list.add("...

weixin_30914981的博客 152

为何不能用 for 循环遍历LinkedList

       点击打开链接        前面提到在使用for循环遍历LinkedList时效率比用 for each 和 Iterator 遍历要低,且随着LinkedList元素增加其差距也越来越大。什么原因呢?看LinkedList的3种遍历代码,List的get()方法源码,Iterator 的 next() 方法源码。public static void main(String[] ar...

obc_132的博客 1349
上一篇: 线程饥饿死锁
下一篇: 《Java并发编程实战》笔记1——Java线程安全基础
ack_Finding
博客等级 码龄10年 6粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值