
Java Iterator原理分析
所有Iterator都最终实现接口Iterator,Iterator接口中包含三个基本方法,next(), hasNext(), remove(),其中对于List的遍历删除只能用Iterator的remove方法;JDK1.8中Iterator接口的源码如下:
下面将基于ArrayList的Iterator的实现分析Iterator的原理(基于JDK1.8):
1.在ArrayList类中有个方法iterator(),此方法将返回一个iterator的实现,这里可以看出实现类叫Itr,通过其它源码可知,此类是AarryList的内部类,即ArryList的Iterator实现在ArrayList内部;
2.下面重点看下ArrayList中实现类Itr类的源码:
从上面代码中可以看出,对于Iterator的实现中主要有几个变量cursor,lastRest, expectedModCount三个变量,其中cursor将记录下一个位置,lastRet记录当前位置,expectedModCount记录没有修改的List的版本号。
问题:还记得说List中在iterator遍历的时候,不能随便添加和删除元素吗,这是为什么呢?
在iterator遍历的时候抛出异常都是checkForComodification作的,根本原因是modCout和expectedModCount不相等,导致抛出异常
那为啥会不相等呢?
可以看看ArrayList的add和remove方法,
remove方法:
add方法:
从上面的代码中可以看出只要对ArrayList作了添加或删除操作都会增加modCount版本号,这样的意思是在迭代期间,会不断检查modCount和迭代器持有的expectedModCount两者是不是相等,如果不想的就抛出异常了。
这样在迭代器迭代期间不能对ArrayList作任何增删操作,但是可以通过iterator的remove作删除操作,从之前的代码可以看出,在iterator的remove()中有一行代码,expectedModCount = modCount; 这个赋值操作保证了iterator的remove是可用性的。
当然,iterator期间不能增删的根本原因是ArrayList遍历会不准,就像遍历数组的时候改变了数组的长度一样
作者:0li0
来源:CSDN
