目录
迭代器
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.通过迭代器可以删除元素。