我们可以看到,通过实现iterator()这个方法,返回了一个Iterator的对象
public Iterator<E> iterator() {
return new Itr();
}
Itr是一个内部类,实现了Iterator接口,在这里面实现了hasNext(),next(),remove(),forEachRemaining()方法,
返回的便是由该类生成的对象
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
// prevent creating a synthetic constructor
Itr() {}
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();
}
}
@Override
public 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 traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
最后的checkForComodification方法,其实是用来检查在迭代过程中有无被修改,如果被修改的话抛出ConcurrentModificationException异常,避免了混乱。
next,remove方法中我们也可以看出不能还没有操作next方法便使用remove方法,便会抛出异常illegalStatementException,原因就是如果还没有使用next方法,lastEct=-1,而remove方法中当lastect<0时,便会抛出异常,同理也可得知,当remove一个元素后,lastEct便会变为-1,再次使用remove也会抛出异常。
public class Main {
public static void main(String[] args) {
// write your code here
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("the");
arrayList.add("first");
arrayList.add("test");
arrayList.add("second");
Iterator itr = arrayList.iterator();
itr.remove();
}
}
ArrayList除了实现Iterator,还实现了ListIterator迭代器
ListIterator继承了Itr,就是上面那个内部类,还实现了ListIterator接口,而ListIterator接口又继承了Iterator接口,
所以ListIterator有Iterator的所有方法。
private class ListItr extends Itr implements ListIterator<E>
listiterator增添的新方法
在这其中,listiterator新添的一个add方法,我们可以看到,如果多次使用add方法,所添加的元素将会一次被放到当前游标元素之前,这些元素在添加的过程就还是有序加入集合中,并且是放在previous和next这两个游标之间。每一次添加游标都会向右移一位。
public void add(E e) {
checkForComodification();
try {
int i = cursor;
ArrayList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
这里用到的是ArrayList.add(int index,Element e)方法。
public void add(int index, E element) {
rangeCheckForAdd(index);
modCount++;
final int s;
Object[] elementData;
if ((s = size) == (elementData = this.elementData).length)
elementData = grow();
System.arraycopy(elementData, index,
elementData, index + 1,
s - index);
elementData[index] = element;
size = s + 1;
}
总结:迭代器的使用将访问逻辑与数据结构分离开来,不同的数据结构都可以用同样的逻辑来读取这些数据。
在collection继承的Iterable接口,则所有的集合都将会实现迭代器。
Iterator是基本的迭代器,实现了hasnext()、next()、remove()几个方法,其中需要注意的是如果没有先使用next()方法,便使用remove()方法,将会抛出illegalStateException异常。而且也不可连续使用remove方法,不然同样会抛出异常。
ListIterator是在Iterator的基础上增添了一些方法,其中的add方法可以将一些元素有序的添加到某个元素之前,即next游标所在元素的前方,按加入顺序进行排列