前言
在使用迭代器的时候,我总是被next(),hasNext()到底指向哪一个元素给迷惑,这次自己读了读原码,总算对相关的知识有了一丁点了解,这次就来分享一下。
原码解析
对于hasNext()
public boolean hasNext() {
return cursor != size;
}
其实现方式是如果游标还没有达到容器的size大小,就返回true,这里与许多人解释的方式不一样, hasNext()不是指有没有下一个元素,而是指有没有当前元素,不然按照很多讲解方法,判断有没有下一个元素,那每次ArrayList中的最后一个元素不就遍历不到了吗?
下面我来画一个图,更好的说明一下
这里放一个size=7 的数组
可以看到,当cursor指向最后一个元素,即cursor=6时,hasNext()返回的是true,而不是返回的元素6的后一个元素,所以我个人认为,hasNext()这个函数名有一点迷惑性,如果改成hasCurrent()可能会好一点。
同理,对于next(),返回的也不是下一个元素
public E next() {
checkForComodification();
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];//i 存储的是游标cursor改变之前的值
}
我们看到next()的原码,它是取出当前元素,然后将游标cursor后移一位
下面我再画一个图解释一下
这里假设游标在调用next()方法前指向的是元素3
调用next方法时,游标先后移一位,但要记录下移动之前的位置i
然后返回游标移动前位置的值
可见,next()中的next,不是为了取游标的下一个元素,而是在取完当前元素后,将游标往后移一位。
总结
对于代码的学习,我不喜欢只看帮助文档,只知道怎么使用的“不求甚解”学习法,要在力所能及的情况下,尽可能知道方法的底层实现的学习方法,才是学习代码的正道。