JavaSE -- 迭代器的源码分析

本文详细解析了ArrayList迭代器的工作机制,包括hashNext和next方法的执行过程,强调了并发修改异常和迭代器使用限制。重点讲解了如何遍历和理解Itr内部结构以及注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

迭代器

代码

源码

迭代器

 一、进入iterator:

一、1. 进入 Itr :

一、1.1. 第一次执行hashNext :

一、1.2. 第一次执行next :

二、2.1. 第二次执行hashNext :

二、2.1. 第二次执行next :

三、3.1. 最后一次执行hashNext :

总结

注意事项


迭代器

1.迭代器集合中的特有的遍历方式

2.增强for底层实现

代码

源码

迭代器

 一、进入iterator:

        得到:

        发现 iterator() 帮咱们创建了一个对象(new Itr())。

        Itr() 就是迭代器对象。

一、1. 进入 Itr :

 

我们发现,Itr 是 ArrayList 的内部类。里面有 hashNext()、next()、remove() 等等。

        分析:

        cursor 默认是 0 。

        lastRet = -1 。

        而 modCount 是 3 。-- 原因是 modCount 初始是 0 。但是每 add 一次就加 1 。

        所以此时:

        modCount = 3 。

        expectedModCount = 3 。

一、1.1. 第一次执行hashNext :

        判断 cursor 是否等于 size 。

                我们知道 size 是集合元素个数 。

        size = 3 。

        0 != 3 。所以返回的是true。

一、1.2. 第一次执行next :

语句:checkForComodification();

        首先,我们进入checkForComodification();可以看到:

        modCount != expectedModCount

        modCount = 3 。expectedModCount = 3 。条件不成立,所以不进入。

        如果条件成立:throw new ConcurrentModificationException()

                这条语句是抛一个异常:并发修改异常,所以迭代器里不允许修改和删除。

语句:int i = cursor;

        因为 cursor = 0 。

        此时 i = 0;

语句:if (i >= size)

                        throw new NoSuchElementException();

        判断 i 是否大于 size 。

        0 > 3 。条件不成立,不执行里面语句。

语句:Object[] elementData = ArrayList.this.elementData;

        这行代码意思是将ArrayList里的底层数组赋值给了elementData。

语句:if (i >= elementData.length)

                         throw new ConcurrentModificationException();

        判断 i 是否 大于这个数组的长度。

        此时 elementData.length = 10 。

        条件不成立,不执行里面语句。

语句:cursor = i + 1;

        此时 cursor = 1 。

语句:return (E) elementData[lastRet = i];

        返回 elementData[lastRet = i];

        前面说过 lastRet = -1,现在将 i 赋值给 lastRet。

        此时 lastRet = 0 。

        所以返回的是 elementData[0] 。也就是你存入的 0 索引的数据。

第一次结束后的值:

lastRet = 0 。

cursor = 1 。

二、2.1. 第二次执行hashNext :

        前面可知 cursor = 1 。 size = 3 。

        条件成立,继续执行下面语句。

二、2.1. 第二次执行next :

语句:checkForComodification();

        首先,我们进入checkForComodification();可以看到:

modCount != expectedModCount

        modCount = 3 。expectedModCount = 3 。条件不成立,所以不进入。

语句:int i = cursor;

        此时 i = 1 。

语句:if (i >= size)

                        throw new NoSuchElementException();

        1 > 3 。条件不成立,不执行里面语句。

语句:Object[] elementData = ArrayList.this.elementData;

        这行代码意思是将ArrayList里的底层数组赋值给了elementData。

语句:if (i >= elementData.length)

                         throw new ConcurrentModificationException();

        判断 i 是否 大于这个数组的长度。

        此时 elementData.length = 10 。

        条件不成立,不执行里面语句。

语句:cursor = i + 1;

        此时 cursor = 2 。

语句:return (E) elementData[lastRet = i];

        返回 elementData[lastRet = i];

        前面说过 lastRet = -1,现在将 i 赋值给 lastRet。

        此时 lastRet = 1 。

        所以返回的是 elementData[1] 。也就是你存入的 1 索引的数据。

第二次结束后的值:

lastRet = 1 。

cursor = 2 。

第三次结束后的值:

lastRet = 2 。

cursor = 3 。

三、3.1. 最后一次执行hashNext :

此时 cursor = 3 。 size = 3 。

所以条件不成立,返回 false 。结束while循环。

总结

1.list.iterator();

        创建了一个迭代器对象,迭代器类Itr,它是ArrayList的内部类

2.Itr 成员属性 cursor 初始值为0 游标

3.hasNext()

        源码 是判断 cursor != size

        第一次判断 0 != 3 为true

4.next()

        4.1 先去判断是否有并发修改异常如果没有进行下一步

        4.2 从底层数组中取出0下标的元素 “张三”

        4.3 游标 cursor = 0 + 1; //此时cursor为1

5. hasNext() 此时cursor != size

                第二次判断 1 != 3 为true

        next()

                从数组中取出1下标的元素 “李四”

                游标 cursor = 1 +1;// cursor 为2

6. 再执行hashNext()

                cursor != size

                2 != 3 ;为true

        进入循环体

        next();

                数组中取 2下标的元素 "王五"

                游标 cursor = 2 +1; //cursor 为3

7. 再执行hashNext()

                cursor != size

                3 != 3 ;//false

                while循环结束

注意事项

1.通过迭代器遍历时,不能对集合的元素进行增删,否则会报并发修改异常。

2.同一个迭代器只能遍历一次。

3.通过迭代器可以删除元素。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值