AbstractList抽象类
第1部分 AbstractList介绍
AbstractList简介
AbstractList继承AbstractCollection,实现List接口,因此除了具有集合的方法属性外,还具有固定顺序,以及索引特征。
AbstractList源码中包含了四个类Itr ,ListItr,SubList,RandomAccessSubList,分别来支持迭代和获取子列表。
AbstractList构造函数
修饰语和返回类型 | 方法 | 描述 |
---|---|---|
protected | AbstractList() |
AbstractList常用API
修饰语和返回类型 | 特殊方法 | 描述 |
---|---|---|
List<E> | subList(int fromIndex, int toIndex) | 获取子列表 |
protected void | removeRange(int fromIndex, int toIndex) | 移除[fromIndex,toIndex)里的元素 |
private void | rangeCheckForAdd(int index) | 检查添加的index索引是否在范围[0,size]内 |
private String | outOfBoundsMsg(int index) | 返回越界信息 |
抽象方法 | ||
E | get(int index) | 获取index所在位置元素 |
第2部分 AbstractList数据结构
AbstractList的继承关系
java.lang.Object
↳ java.util.AbstractCollection<E>
↳
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {}
AbstractList的关系图
图1 AbstractList的关系图
看到这个关系,我也是有点惊了,买一送四,里面定义了四个类,总共五个类。遇到这种情况,逐个击破就行了,先从被依赖的类开始,父类到子类的顺序开始分析。此外,modCount记录的时修改次数(针对增删改操作),用于fast-fail机制。
第3部分 AbstractList源码解析(基于JDK-8u201)
内部迭代器Itr
private class Itr implements Iterator<E> {
//下一元素指针,用来标记遍历到了哪里
int cursor = 0;
//上次返回元素指针,记录上次返回了哪个元素
int lastRet = -1;
//期待更改次数,用作fast-fail机制
int expectedModCount = modCount;
public boolean hasNext() {
//下一元素指针没到最末,表示还有元素
return cursor != size();
}
public E next() {
//fast-fail机制,检查expectedModCount是否等于modCount,不等于则抛异常
checkForComodification();
try {
int i = cursor;
//获取下一元素
E next = get(i);
//修改上次返回元素的值
lastRet = i;
//下一元素指针后移
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
//移除上次调用next()时返回的元素,也就是上次返回元素
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
//调用AbstractList实例对象的remove(index),注意该方法会修改modCount
AbstractList.this.remove(lastRet);
//移除的时候,后面的元素会往前移动,因此cursor也要前移
if (lastRet < cursor)
cursor--;
lastRet = -1;
//调用remove的时候modCount+1了,因此要修改expectedModCount,
//否则,后面checkForComodification都会报错
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
//并发修改异常,这个异常在fast-fail中很常见,也就是在不支持并发的类中很常见
throw new ConcurrentModificationException();
}
}
Itr 相比于迭代器接口,也就是多了cursor , lastRet , expectedModCount 三个成员来作为标记,其他跟普通迭代器接口没多大区别。
内部迭代器ListItr
//以下方法都继承ListIterator的方法
private class ListItr extends Itr implements ListIterator<E> {
//构造函数,可指定起始遍历下表
ListItr(int index) {
cursor = index;
}
//向前遍历
public boolean hasPrevious() {
//下一元素指针不为0,说明前面还有元素
return cursor != 0;
}
//获取上一个元素,原理和Itr获取下一个元素一样
public E previous() {
checkForComodification();
try {
int i = cursor - 1;
E previous = get(i);
lastRet = cursor = i;
return previous;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
public int nextIndex() {
return cursor;
}
public int previousIndex() {
return cursor-1;
}
//修改上次返回的元素为e
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
//直接调用外部对象的修改方法
AbstractList.this.set