ArrayList的迭代器
案例一:已知集合 List 泛型是String
里面有三个元素 ,迭代器遍历获取
//操作 Iterator iterator = arrayList1.iterator()
// while ( iterator.hasNext() ) {
// System.out.println(iterator.next());
// }
public Iterator iterator() {
// 内部类
return new Itr();
}
private class Itr implements Iterator {
// 迭代器的光标
int cursor; // index of next element to return
// 上一次元素返回的位置
int lastRet = -1; // index of last element returned; -1 if no such
// 将集合的修改次数 赋值给 预期修改次数
int expectedModCount = modCount;
Itr() {}
// 是否有下一个元素
public boolean hasNext() {
// 当前光标是不是等于size大小
return cursor != size;
}
// next方法
@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];
}
// 校验预期修改集合次数是否和实际修改集合次数一样
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
...其他方法...
}
案例二
集合中有 hello java PHP 三个字符串
在迭代器迭代时判断
如果时PHP 就 list.remove删除掉PHP
// add方法
public boolean add(E e) {
// 在这里 修改了modCount 集合修改次数
// 案例中所有的add执行完 = 3
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
// remove方法
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
// 用想要删除的元素和集合中的每一个元素比较
if (o.equals(elementData[index])) {
// 真正删除的方法
fastRemove(index);
return true;
}
}
return false;
}
private void fastRemove(int index) {
// 实际修改次数会变化
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
// 尽快被垃圾回收
elementData[--size] = null; // clear to let GC do its work
}
public Iterator iterator() {
// 内部类
return new Itr();
}
private class Itr implements Iterator {
// 迭代器的光标
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
// 将集合的修改次数 赋值给 预期修改次数
// 获取到迭代器的时候 expectModeCount = modCount = 3
int expectedModCount = modCount;
Itr() {}
// 是否有下一个元素
// 在删除掉一个元素后 集合的大小被修改为了2 这个时候是不相等的!!!!!!!!!
// 所以会再执行一次next方法 这次就会引发异常
public boolean hasNext() {
// 当前光标是不是等于size大小
return cursor != size;
}
// next方法
@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];
}
// 校验预期修改集合次数是否和实际修改集合次数一样
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
...方法...
}
// 结论
// 集合调用add时 实际修改次数 那个变量 会+1
// 获取迭代器时 预期修改次数 被赋值 一次
// 删除元素后 就会引发并发修改异常
案例三
集合中有 hello PHP java 三个字符串
在迭代器迭代时判断
如果时PHP 就 list.remove删除掉PHP
PHP在倒数第二个的位置
// 正常添加结束 // 要删除的元素在集合的倒数第二个位置时不会产生异常 // 原因时在调用hasNext时 光标的值和集合的长度一样 // 不会调用next方法 // 底层就不会产生并发修改异常



