什么是迭代器:
维基百科解释:迭代器(iterator)有时又称光标(cursor)是程序设计的软件设计模式,可在容器对象(container,例如链表或数组)上遍访的接口,设计人员无需关心容器对象的内存分配的实现细节。
我们解释一下上面这段话:
讲到迭代器,就离不开容器,也是是Java中经常讲到的集合(Java集合框架的集合类,我们有时候称之为容器)。容器的种类有很多种,比如ArrayList、LinkedList、HashSet…,(这里我们先不考虑Map接口下面的类)每种容器都有自己的特点,ArrayList底层维护的是一个数组;LinkedList是链表结构的;HashSet依赖的是哈希表,每种容器都有自己特有的数据结构。
正是因为容器的内部结构不同,所以很多时候可能不知道该怎样去遍历一个容器中的元素。所以为了使对容器内元素的操作更为简单,Java引入了迭代器模式,把迭代抽取为一个接口,更为简洁高效的实现容器的遍历!
把访问逻辑从不同类型的集合类中抽取出来,从而避免向外部暴露集合的内部结构,达到设计人员无需关心容器对象的内存分配的实现细节的目的。
查看Iterator接口源码,发现Iterator主要有三个方法:hasNext()、next()、remove()


我们以一个具体的类来看迭代器的原理和实现过程(以ArrayList为例)
1、hasNext()方法
可以看到,hasNext方法官方说明是判断是否存在下一个元素,这里通过cursor是否与集合中的元素个数相同来判断集合中元素是否遍历完毕,如果没有,就返回true。
2、next()方法
注意:这里新创建的迭代器默认指向列表中的第一个元素!!!
这里调用next()方法,是返回当前元素, 指针(cursor)并指向下一个元素。这里跟我们前面那个Iterator那里的说法我觉得是有点冲突的—-Returns the next element in the iteration.(其实我这里也没品出来,不过我们清楚源码怎么实现就行了,网上各有各的说法,有的说返回当前,有的说返回下一个,与其说这么多,不如看看源码怎么实现)
3、remove()方法
remove()删除next方法返回的元素,一般和next方法一起用。这里注意如果调用remove之前没有调用next是不合法的,会抛出IllegalStateException。迭代器的remove操作删除的是最近一次由next操作获取的元素,而不是当前游标所指向的元素。
这里插着讲一下,Iterator遍历时不可以删除集合中的元素问题
在使用Iterator的时候禁止对所遍历的集合进行改变其大小结构的操作。例如: 在使用Iterator进行迭代时,如果对集合进行了add、remove操作就会出现ConcurrentModificationException异常,除非通过迭代器自身的remove或add方法(比如ListIterator中的add方法)从结构上对列表进行修改。
原因是因为在你迭代之前,迭代器已经被创建出来了(比如Iterator it = list.iterator();),如果在迭代的过程中,又对list进行了改变其集合大小的操作,那么Java就会给出异常。因为此时Iterator对象已经无法主动同步list做出的改变,Java会认为你做出这样的操作是线程不安全的,就会给出善意的提醒(抛出ConcurrentModificationException异常)
实现过程就是通过checkForComodification()方法,具体实现可以详细看源码!
这里附上一位博主的详细解释:深入理解Java中的迭代器

文章末尾附上ArrayList中迭代器一段详细源码
private class Itr implements Iterator<E> {int cursor; // index of next element to returnint lastRet = -1; // index of last element returned; -1 if no suchint expectedModCount = modCount;// prevent creating a synthetic constructorItr() {}public boolean hasNext() {return cursor != size;}@SuppressWarnings("unchecked")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];}public void remove() {if (lastRet < 0)throw new IllegalStateException();checkForComodification();try {ArrayList.this.remove(lastRet);cursor = lastRet;lastRet = -1;expectedModCount = modCount;} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}@Overridepublic void forEachRemaining(Consumer<? super E> action) {Objects.requireNonNull(action);final int size = ArrayList.this.size;int i = cursor;if (i < size) {final Object[] es = elementData;if (i >= es.length)throw new ConcurrentModificationException();for (; i < size && modCount == expectedModCount; i++)action.accept(elementAt(es, i));// update once at end to reduce heap write trafficcursor = i;lastRet = i - 1;checkForComodification();}}final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();}}
