一.不论ListIterator还是SubList,均是对ArrayList维护的数组进行操作
首先我得说下 ListIterator 是什么, ListIterator 与 Iterator 均是迭代器接口,对应 ArrayList 中的实现就是 ListItr 与 Itr ,我们使用 ListIterator 或 SubList 的过程中很少对ArrayList的操作,如果有那就很严重了(下面会说的),对源数组进行操作这是一个事实存在的问题:joy:,尤其在SubList表现的尤为严重~
先看看 ArrayList 的 subList 方法定义:
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, 0, fromIndex, toIndex);
}
可以看到 subList 方法返回的是 SubList 的一个实例,好,继续看构造函数定义:
private class SubList extends AbstractList<E> implements RandomAccess {
private final AbstractList<E> parent;
private final int parentOffset;
private final int offset;
int size;
// SubList构造函数的具体定义
SubList(AbstractList<E> parent, int offset, int fromIndex, int toIndex) {
// 从offset开始截取size个元素
this.parent = parent;
this.parentOffset = fromIndex;
this.offset = offset + fromIndex;
this.size = toIndex - fromIndex;
this.modCount = ArrayList.this.modCount;
}
首先我们要清楚的是 subList 对源数组( elementData )的取用范围 是 fromIndex <=取用范围< toIndex , 这里用 取用范围 其实很准确,接着看~ 因为 return new SubList(this, 0, fromIndex, toIndex); 对应构造函数的第一个参数 parent 其实也就是当前ArrayList的实例对象,这是其一,还有就是SubList的offset是默认的 offset+ fromIndex ,取用的范围就 size 限制在 toIndex - fromIndex; 以内,不管是 ArrayList 还是 SubList 对数组( elementData )的偏移操作,只不过一个是从0开始一个是从 offset + fromIndex; 开始~,如果你还是存在怀疑的话,先看看 SubList 中 get`方法:
public E get(int index) {
rangeCheck(index);
checkForComodification();
return ArrayList.this.elementData(offset + index);
}
看到没, get 方法也只直接取用的原数组( elementData )-> return
ArrayList.this.elementData(offset + index); ,很明白了吧,再看看 SubList 中 remove 方法论证下当前这个小标题哈~
public E remove(int index) {
rangeCheck(index);
checkForComodification();
E result = parent.remove(parentOffset + index);
this.modCount = parent.modCount;
this.size--;
return result;
}
我在前面说过,这个 parent 其实也就是当前 ArrayList 的