一、 提供公开的iterator方法以内部类的形式Itr是ListItr的父类:
1.iterator方法:
public Iterator<E> iterator() {
return new Itr();
}
2.hasNext方法和next方法:
具体内部信息如下:
private class Itr implements Iterator<E> {//实现了Iterator接口
int cursor; // index of next element to return 下一个返回元素的下标,无需初始化,在类的准备阶段自动赋值为0
int lastRet = -1; // index of last element returned; -1 if no such 最后一元素的返回值
int expectedModCount = modCount;//增减操作次数
Itr() {}//构造方法
public boolean hasNext() {
return cursor != size;//很好理解的是cursor等于size时,next元素就超出下标 从而异常
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();//检查当前list元素是否被修改,生成迭代器之后,若元素值发生了数量的变化,就会抛出异常,修改不会产生异常,由此可以看出ArrayList是线程不安全的,会出现读不一致问题
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];//返回对应下标的的元素
}
3.remove方法:
public void remove() {//iterator内部的移除方法
if (lastRet < 0)//所有移除之后就会有异常
throw new IllegalStateException();
checkForComodification();//检验是否原List数量发生了变化
try {
ArrayList.this.remove(lastRet);//调用ArrayList自身的remove方法
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
4.forEachRemaining方法:
@Override//重写的迭代器方法
@SuppressWarnings("unchecked")//遍历剩余的元素,由此实现二分查找算法
public void forEachRemaining(Consumer<? super E> consumer){//接收一个consumer接口重写 accpt方法
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();//都要进行元素变化检验
}
二、第二个内部类ListItr
1.带参数:参数代表迭代指定数组下标,0<index<this.elementData.size,从指定index开始遍历
public ListIterator<E> listIterator(int index) {
if (index < 0 || index > size)//下标校验
throw new IndexOutOfBoundsException("Index: "+index);
return new ListItr(index);
}
2.无参:可从初始位置遍历
public ListIterator<E> listIterator() {//通过new内部类实例实现List双向遍历
return new ListItr(0);
}
3.设计原理逻辑:都是私有化内部类,提供公共的获取方法。
private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) {
super();
cursor = index;
}
public boolean hasPrevious() {//判断是否前驱元素
return cursor != 0;
}
public int nextIndex() { //获取下一个元素的下标
return cursor;
}
public int previousIndex() {//获取前驱元素下标
return cursor - 1;
}
@SuppressWarnings("unchecked")
public E previous() {
checkForComodification();//这个函数很简单就是校验expectedModcount和真实ModCount是否相等,从而决定程序是否继续执行,还是异常终止
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[lastRet = i];
}
public void set(E e) {//只能给当前遍历到的值进行赋值
if (lastRet < 0)//检验下标合理性
throw new IllegalStateException();
checkForComodification();//检查元素变动
try {
ArrayList.this.set(lastRet, e);//通过类内部
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public void add(E e) {
checkForComodification();//元素变动检验
try {
int i = cursor;
ArrayList.this.add(i, e);//通过调用类内部的方法实现增加
cursor = i + 1;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
三、第三个内部类 subList
1**函数说明:**获取对应区间的子List,第一个代表起始位置,第二个代表结束位置
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);//下标范围检验
return new SubList(this, 0, fromIndex, toIndex);
}
2.内部类具体构成:
private class SubList extends AbstractList<E> implements RandomAccess {
private final AbstractList<E> parent;//用于接收父级List
private final int parentOffset;//父下标偏移量
private final int offset;//内部偏移量,初始化为0
int size; //List元素个数
SubList(AbstractList<E> parent,
int offset, int fromIndex, int toIndex) {//构造方法:用于构建子类对象
this.parent = parent;
this.parentOffset = fromIndex;
this.offset = offset + fromIndex;
this.size = toIndex - fromIndex;
this.modCount = ArrayList.this.modCount;//由此可知在生成子List之后不可以再通过原类实例进行元素数量的更改
}
public E set(int index, E e) {
rangeCheck(index);
checkForComodification();
E oldValue = ArrayList.this.elementData(offset + index);
ArrayList.this.elementData[offset + index] = e;
return oldValue;
}
public E get(int index) {
rangeCheck(index);
checkForComodification();
return ArrayList.this.elementData(offset + index);
}
public int size() {
checkForComodification();
return this.size;
}
public void add(int index, E e) {
rangeCheckForAdd(index);
checkForComodification();
parent.add(parentOffset + index, e);
this.modCount = parent.modCount;
this.size++;
}
public E remove(int index) {
rangeCheck(index);
checkForComodification();
E result = parent.remove(parentOffset + index);
this.modCount = parent.modCount;
this.size--;
return result;
}
protected void removeRange(int fromIndex, int toIndex) {
checkForComodification();
parent.removeRange(parentOffset + fromIndex,
parentOffset + toIndex);
this.modCount = parent.modCount;
this.size -= toIndex - fromIndex;
}
public boolean addAll(Collection<? extends E> c) {
return addAll(this.size, c);
}
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
int cSize = c.size();
if (cSize==0)
return false;
checkForComodification();
parent.addAll(parentOffset + index, c);
this.modCount = parent.modCount;
this.size += cSize;
return true;
}
public Iterator<E> iterator() {//生成对应子类的迭代器
return listIterator();
}
**注释:**此处采用直接内部实现一个Listiterator接口,然后用ListIterator接收,同时也要保证List元素个数不可变性,重写需要重写的方法,对于元素的更改内部调用ArrayList的实例方法,要进行modCount修改。
3.内部迭代器实现逻辑
public ListIterator<E> listIterator(final int index) {//子List也可以使用迭代器
checkForComodification();//元素数量变动detect
rangeCheckForAdd(index);//元素越界检验
final int offset = this.offset;//此处的this指的是SubList实例引用
return new ListIterator<E>() {//匿名内部类的形式直接实现一个接口
int cursor = index;
int lastRet = -1;
int expectedModCount = ArrayList.this.modCount;//ArrayList.this 指的是当前ArrayList实例的引用
public boolean hasNext() {
return cursor != SubList.this.size;//因为此时存在父类关系,拥有三个对象实例
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= SubList.this.size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[offset + (lastRet = i)];
}
public boolean hasPrevious() {
return cursor != 0;
}
@SuppressWarnings("unchecked")
public E previous() {
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[offset + (lastRet = i)];
}
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = SubList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (offset + i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[offset + (i++)]);
}
// update once at end of iteration to reduce heap write traffic
lastRet = cursor = i;
checkForComodification();
}
public int nextIndex() {
return cursor;
}
public int previousIndex() {
return cursor - 1;
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
SubList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = ArrayList.this.modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.set(offset + lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public void add(E e) {
checkForComodification();
try {
int i = cursor;
SubList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = ArrayList.this.modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (expectedModCount != ArrayList.this.modCount)
throw new ConcurrentModificationException();
}
};
}
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, offset, fromIndex, toIndex);
}
private void rangeCheck(int index) {
if (index < 0 || index >= this.size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private void rangeCheckForAdd(int index) {
if (index < 0 || index > this.size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+this.size;
}
private void checkForComodification() {
if (ArrayList.this.modCount != this.modCount)
throw new ConcurrentModificationException();
}
}
四、第四个不是内部类而是static-nested类ArrayListSpliterator
1.是一个静态nested类提供全局使用:
SubList调用:
public Spliterator<E> spliterator() {//公共的方法 获取ArrayListSpliterator<E>
checkForComodification();
return new ArrayListSpliterator<E>(ArrayList.this, offset,
offset + this.size, this.modCount);
}
}
ArrayList实例方法:
@Override
public Spliterator<E> spliterator() {
return new ArrayListSpliterator<>(this, 0, -1, 0);
}
2.静态嵌套类类具体实现:
具体作用就是二分遍历:
static final class ArrayListSpliterator<E> implements Spliterator<E> {//实现了Spliterator接口
private final ArrayList<E> list;//用于接收List
private int index; // current index, modified on advance/split
private int fence; // -1 until used; then one past last index
private int expectedModCount; // initialized when fence set
/** Create new spliterator covering the given range */
ArrayListSpliterator(ArrayList<E> list, int origin, int fence,
int expectedModCount) {
this.list = list; // OK if null unless traversed
this.index = origin;
this.fence = fence;
this.expectedModCount = expectedModCount;
}
private int getFence() { // initialize fence to size on first use
int hi; // (a specialized variant appears in method forEach)
ArrayList<E> lst;
if ((hi = fence) < 0) {
if ((lst = list) == null)
hi = fence = 0;
else {
expectedModCount = lst.modCount;
hi = fence = lst.size;
}
}
return hi;
}
public ArrayListSpliterator<E> trySplit() {
int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;//二分计算过程
return (lo >= mid) ? null : // divide range in half unless too small
new ArrayListSpliterator<E>(list, lo, index = mid,
expectedModCount);
}
public boolean tryAdvance(Consumer<? super E> action) {
if (action == null)
throw new NullPointerException();
int hi = getFence(), i = index;
if (i < hi) {
index = i + 1;
@SuppressWarnings("unchecked") E e = (E)list.elementData[i];
action.accept(e);
if (list.modCount != expectedModCount)
throw new ConcurrentModificationException();
return true;
}
return false;
}
public void forEachRemaining(Consumer<? super E> action) {
int i, hi, mc; // hoist accesses and checks from loop
ArrayList<E> lst; Object[] a;
if (action == null)
throw new NullPointerException();
if ((lst = list) != null && (a = lst.elementData) != null) {
if ((hi = fence) < 0) {
mc = lst.modCount;
hi = lst.size;
}
else
mc = expectedModCount;
if ((i = index) >= 0 && (index = hi) <= a.length) {
for (; i < hi; ++i) {
@SuppressWarnings("unchecked") E e = (E) a[i];
action.accept(e);
}
if (lst.modCount == mc)
return;
}
}
throw new ConcurrentModificationException();
}
public long estimateSize() {
return (long) (getFence() - index);
}
public int characteristics() {
return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
}
}
**注:**本文是对源码梳理,关于各个方法的使用场景没有做过多的剖析,可以清楚的理清迭代器的实现原理,深刻的认识到ArryList是线程不安全的,并且Itr用于顺向遍历,而ListItr完美的解决无法获取前驱元素的问题,SubList解决了遍历起始位置的问题,使得获取ArrayList值方法变得多样性,Spliterator的构建可以用于实现一定的算法来提高程序运行效率,从时间复杂度和空间复杂度优化方案。