最近在看集合源码时发现了这两口接口及其容易混淆,于是研究了一下。
Iteratble接口
Iterable接口有两个重要的方法:
- 1.Iterator iterator();
返回一个迭代器,迭代器具有一系列的功能,可以对集合进行遍历或者删除元素等操作。 - 2.void forEach(…);
这个方法为集合进行for循环提供了可能性,如果实现类没有实现这个接口,就不能进行for循环。
Iterator接口
其实Iterator接口是一个为了被实现的接口,接口代表的是一种规范,一种共同的行为。Iterator就是迭代器,是一种工具。
所以,实现类重写了接口的iterator()方法,返回了适合自己使用的迭代器,为JDK的使用者们提供了这个方便的工具。
以下是AbstractorList类对itrator()方法的实现,会返回一个new Itr,Itr是一个内部类,具体代码如下:
private class Itr implements Iterator<E> {
/**
* Index of element to be returned by subsequent call to next.
*/
// 这一个指针
int cursor = 0;
/**
* Index of element returned by most recent call to next or
* previous. Reset to -1 if this element is deleted by a call
* to remove.
*/
// 上一个指针
int lastRet = -1;
/**
* The modCount value that the iterator believes that the backing
* List should have. If this expectation is violated, the iterator
* has detected concurrent modification.
*/
// 用于检测迭代集合时非法删除的数字
// modCount理解为操作次数
int expectedModCount = modCount;
// 集合是否已经迭代完毕
public boolean hasNext() {
return cursor != size();
}
// 指针下移,lastRet指到当前指针的位置
public E next() {
checkForComodification();
try {
int i = cursor;
E next = get(i);
lastRet = i;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
// 这个方法用于检测并发操作,即同一个集合不能同时被两个线程操作,会抛出错误
checkForComodification();
throw new NoSuchElementException();
}
}
/**
* 移除指针所指的上一个元素
*/
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
综上所述,迭代器使用较多的,还是next();和hasNext();方法,千万不要一边迭代一边remove();否则会报错。