ArrayList(JDK8)
- ArrayList有四个内部类,成员内部类Itr,成员内部类ListItr,静态内部类SubList,ArrayListSpliterator(暂时用不到)
- Itr是Iterator的实现类,支持正向遍历,ArrayList的iterator方法返回一个Itr对象
- ListItr是ListIterator的实现类,支持双向遍历,ArrayList的listIterator方法返回一个ListIterator类对象
Itr
-
增强 for 遍历数组时, 被编译成普通 for 循环, 增强 for 遍历集合时, 被编译成使用 Iterator; 无论是数组还是集合, 只用增强 for 都无法修改原本引用的指向;
-
单步迭代中, 不允许多次调用迭代器的 remove 方法; 逻辑上来说, 你迭代一次, 当然只能判断当前的对象是不是需要被删除, 干嘛要多次删除? 其次, 这样也能让迭代器的代码逻辑更简洁, 避免很多边界条件的判断, 也能避免很多潜在的错误;
-
如果要通过循环删除 List 中的所有元素, 可以这样做
for(int i = 0; i < list.size(); i++){ list.remove(i); i--; } // 或者 // removeIf 的本质就是迭代器实现的; list.removeIf(i->true); // 或者通过迭代器;
// ArrayList的
public Iterator<E> iterator() {
return new Itr();
}
// 作为ArrayList的成员内部类
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
// 显式赋值,让自己的expectedModCount = ArrayList.this.modCount
// 在内部类的成员方法和构造函数中,隐含了ArrayList.this和this传参
int expectedModCount = modCount;
// prevent creating a synthetic constructor
Itr() {
}
public boolean hasNext() {
// ArrayList.this.size
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
// 这里修改了所依附的外围类对象arrayList的modCount
ArrayList.this.remove(lastRet);
// 删除时cursor要往前移动一位
cursor = lastRet;
// 防止连续删除
lastRet = -1;
// 更新自己的modCount
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException(