使用迭代器遍历
众所周知,单列集合Collection是一个接口 ,所有单列集合都直接或间接实现了这个接口,Collection接口里定义了一个iterator方法。所以所有单列集合都有这个方法的重写。
public interface Collection<E> extends Iterable<E> {
Iterator<E> iterator();
}
那重写的方法是什么呢,以ArrayList为例跟进
public Iterator<E> iterator() {
return new Itr();
}
发现是返回了一个Itr()对象,这又是什么东西呢,继续跟进
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;
Itr() {}
}
原来是迭代器的一个实现类对象。
好,现在可以来遍历了。
Collection<String> coll = new ArrayList<>();
coll.add("gyl");
coll.add("zys");
coll.add("wym");
Iterator<String> it = coll.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
调用iterator()方法创建一个迭代器指向迭代器接口
那hasNext方法是什么呢
看眼源码
public boolean hasNext() {
return cursor != size;
}
返回是一个boolean值,当cursor 不等于size时返回真
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
cursor是索引值加1(其实就是个指针),当他等于个数时就是遍历结束的时候。
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];
}
首先调用checkForComodification方法
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
检查集合是否在迭代过程中被修改,如果是则抛出ConcurrentModificationException异常。
然后获取当前指针的位置i,如果i超过了集合的大小,则抛出NoSuchElementException异常。
接着获取集合的元素数组elementData,如果i超过了数组的长度,则抛出ConcurrentModificationException异常。
最后将指针后移一位,返回数组中i位置的元素,并将lastRet赋值为i
需要注意的是一个迭代器用完之后就废了,不能重头再来,只能重新弄一个迭代器调用