二、Iterable 迭代器
1、先上代码
public class IteratorExercise {
public static void main(String[] args) {
ArrayList<String> aList = new ArrayList<>();
aList.add("I");
aList.add("HAVE");
aList.add("A");
aList.add("DREAM");
Iterator<String> it = aList.iterator();
while (it.hasNext()) {
String str = it.next();
System.out.println(str);
// aList.add("muy");
}
}
}
把 aList.add("muy");
注释打开运行
这个就涉及到 fail-fast(The returned iterator is fail-fast.) 机制
2、接下来看看这个fail-fast机制原理
根据抛出的异常找到
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
在next()调用这个方法来判断两个变量是否相等,
详细了解过程 调用aList.add("I");
时,点进去
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
这里可以看到每次调用add() , modCount都会自增1,4个add()执行完后 modCount==4
接着走到Iterator<String> it = aList.iterator();
这个方法
public Iterator<E> iterator() {
return new Itr(); //new 了一个Itr类
}
/**
* An optimized version of AbstractList.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; //modCount赋值给expectedModCount
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() { //这个方法就是it.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
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
这里int expectedModCount = modCount;
modCount赋值给expectedModCount
输出了一个 “I”后, 又调用了aList.add("muy");
可以看到此时 modCount已经是5了
接下来走到next(),就调用checkForComodification(),这个方法检查了
remove()方法也是类似的
二、上面是使用迭代器的一种方式,还有一种实现接口
然后foreach循环内部实现机制不是很清楚
参考:
http://blog.csdn.net/lcore/article/details/12083951
http://openhome.cc/Gossip/JavaEssence/Foreach.html