java源码之AbstractList
- 前言
- 继承关系
- 源码
- 成员变量
- modCount
- 内部类
- 内部类Itr
- 成员变量
- cursor
- lastRet
- expectedModCount
- 方法
- hasNext
- next
- remove
- 内部类 ListItr
- 构造函数
- 方法
- hasPrevious
- previous
- nextIndex
- previousIndex
- add
- set
- 已实现方法
- add
- addAll
- clear
- indexOf
- iterator
- lastIndexOf
- listIterator
- subList
- 未实现方法
- add
- get
- set
- 结束语
前言
这个类提供List接口的基础实现,对于按照顺序存储的数组优先集成这个类。
实现一个不可修改的数组仅需要实现get(int)和size()方法即可;
要是实现一个可以修改的数组必须重写set(int,E)方法(否则会抛出一个UnsupportedOperationException ),如果数组的大小是可变的必须冲写add(int, E)和remove(int)方法。
继承关系
这个类继承自AbstractCollection抽象类同时实现了List接口
源码
成员变量
modCount
protected transient int modCount = 0
这个变量被transient修饰,代表其不可被序列化,这个值记录这个数组被改变次数,用来实现fast-fail策略。如果你想自己建一个集合类你需要自行维护这个变量。
内部类
内部类Itr
private class Itr implements Iterator<E> {
/**
* 下一个调用next访问元素的下标
*/
int cursor = 0;
/**
* 上一个访问(返回)元素的下标
*/
int lastRet = -1;
/**
* 期望修改次数
*/
int expectedModCount = modCount;
/**
* 判断是否包含下一个元素
* 判断方法 是利用下一个访问元素的下边和数组的大小不同
*/
public boolean hasNext() {
return cursor != size();
}
/**
* 获得下一个元素
*/
public E next() {
// 判断是否修改 修改执行fail-fase策略直接抛出异常
checkForComodification();
try {
// 获取当前需要获得的值下标
int i = cursor;
// 获取当前访问的值
E next = get(i);
// 将当前访问值的下标放入上一次访问中
lastRet = i;
//下次访问下表加1
cursor = i + 1;
// 返回
return next;
} catch (IndexOutOfBoundsException e) {
// 抛出异常后 首先进行判断是否存在 如果存在修改就抛出ConcurrentModificationException否则就抛出NoSuchElementException
checkForComodification();
throw new NoSuchElementException();
}
}
/**
* 删除当前元素
*/
public void remove() {
// 判断上次访问值
if (lastRet < 0)
throw new IllegalStateException();
// 判断是否修改 修改执行fail-fase策略直接抛出异常
checkForComodification();
try {
// 调用remove方法移除元素
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
//下一个要访问的下表减1
cursor--;
// 上次访问重新归为-1
lastRet = -1;
// 修改迭代器期望值(下次调用next()不回出现ConcurrentModificationException)
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
/**
* 判断元素是否有修改
* 判段是利用期望修改值是否等于真实修改值
*/
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
成员变量
cursor
int cursor = 0;
下一个要访问元素的下
- 调用next()方法在获取到相应的元素的同时,cursor变量的数值会递增;
- -当调用Itr.remove方法是cursor值会减1,以保证能把数据完全迭代。
lastRet
int lastRet = -1;
上一次访问的数据的下标
- 调用next()方法也会把调用之前的cursor值赋值给lastRet;
- 调用remove时会把他的值修改为-1,等待下次调用next()方法。
expectedModCount
int expectedModCount = modCount;
期望修改次数,在创建迭代器的时候,会把集合的modCount 数据的值放入这个变量中,之后判断这个值和集合的modCount是否相等,判断数据是否有修改,并执行fail-fase策略。
方法
hasNext
public boolean hasNext() {
return cursor != size();
}
判断是否仍旧存在未迭代遍历的元素,判断调教为下表是否等于集合的长度。
next
public E next() {
// 判断是否存在改变
checkForComodification();
try {
// 获取当前操作的下表
int i = cursor;
// 调用集合的get(int)方法获取数据
E next = get(i);
// 将当前操作下表设置为上次访问
lastRet = i;
// 当前操作下标+1作为下次访问的小标
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
// 存在数组下表方法问题
//首先判断数组是否进行了修改 存在修改就抛出ConcurrentModificationException
checkForComodification();
// 否则抛出NoSuchElementException
throw new NoSuchElementException();
}
}
这个方法用来获取迭代器的元素,在操作开始前会先进行判断数组是否存在改动checkForComodification(),如果改动就抛出异常,为改动就进行正常访问。这个方法多次调用checkForComodification()方法
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
判断期望修改值和数组中的修改值是否相同
remove
public void remove() {
// 当为开始访问数或者本次访问的数据已经被删除是lastRet会为-1,此时进行判断是否有可以删除数据
if (lastRet < 0)
throw new IllegalStateException();
// 判断数组是否发生改变
checkForComodification();
try {
// 调用集合的remove方法,删除数据为最近访问数据
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
// 修改迭代器期望值(下次调用next()不回出现ConcurrentModificationException)
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
内部类 ListItr
private class ListItr extends Itr implements ListIterator<E> {
// 构造函数
// 从index开始进行迭代
ListItr(int index) {
cursor = index;
}
// 是否有前一个元素
public boolean hasPrevious() {
return cursor != 0;
}
//获取前一个元素
public E previous() {
// 检查是否有修改元素
checkForComodification();
try {
// 获取当前数据下表
int i = cursor - 1;
// 调用集合get方法获取数据
E previous = get(i);
// lastRet 上一次访问(返回)元素的下标 调用get(i)返回的数据 所以 lastRet =i
// cursor 使用next方法需要返回的数据 i这个下标的数据已经被获取了 也就是下标实际位置已经不在i上了 所以再次调用next方法返回的应该是i这个下表的数据 所以cursor = i
lastRet = cursor = i;
return previous;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
// 获取当前下标
public int nextIndex() {
return cursor;
}
// 获取上次访问下标
public int previousIndex() {
return cursor-1;
}
// 修改当前值
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
// 检查修改
checkForComodification();
try {
// 调用set修改数据
AbstractList.this.set(lastRet, e);
// 修改迭代器期望值(下次调用next()不回出现ConcurrentModificationException)
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
// 在当前位置插入一个数据
public void add(E e) {
checkForComodification();
try {
// 获取当前位置
int i = cursor;
// 调用add方法今夕插图
AbstractList.this.add(i, e);
// 上次访问设置为-1
lastRet = -1;
// 下标+1
cursor = i + 1;
// 修改迭代器期望值(下次调用next()不回出现ConcurrentModificationException)
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
构造函数
ListItr(int index) {
cursor = index;
}
创造一个从index开始的ListIterator。
方法
hasPrevious
public boolean hasPrevious() {
return cursor != 0;
}
是否有前一个元素的判断方式是游标所处的位置是否为0;
previous
public E previous() {
// 检查是否有修改元素
checkForComodification();
try {
// 获取当前数据下表
int i = cursor - 1;
// 调用集合get方法获取数据
E previous = get(i);
lastRet = cursor = i;
return previous;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
获取上一个元素
nextIndex
public int nextIndex() {
return cursor;
}
正序访问下一个下标
previousIndex
public int previousIndex() {
return cursor-1;
}
获取正序访问上一个访问数据的下表
add
public void add(E e) {
checkForComodification();
try {
int i = cursor;
AbstractList.this.add(i, e);
lastRet = -1;
cursor = i + 1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
在当前位置添加一个数据
set
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
// 检查修改
checkForComodification();
try {
// 调用set修改数据
AbstractList.this.set(lastRet, e);
// 修改迭代器期望值(下次调用next()不回出现ConcurrentModificationException)
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
修改当前位置的数据
已实现方法
add
在集合结尾添加一个元素调用了add(int, Object)方法,由于这个方法的实现是直接抛出一个异常所以帮他放到未实现里面
public boolean add(E e) {
add(size(), e);
return true;
}
addAll
从指定的位置开始将新的集合中的元素加入集合中,同理调用add(int, Object)方法
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
boolean modified = false;
for (E e : c) {
add(index++, e);
modified = true;
}
return modified;
}
clear
public void clear() {
removeRange(0, size());
}
protected void removeRange(int fromIndex, int toIndex) {
// 获取一个从fromIndex开始的ListIterator迭代器
ListIterator<E> it = listIterator(fromIndex);
for (int i=0, n=toIndex-fromIndex; i<n; i++) {
// 循环调用next和remove删除
it.next();
it.remove();
}
}
删除从开始到结束的元素,利用迭代器进行删除
indexOf
public int indexOf(Object o) {
ListIterator<E> it = listIterator();
if (o==null) {
while (it.hasNext())
if (it.next()==null)
return it.previousIndex();
} else {
while (it.hasNext())
if (o.equals(it.next()))
return it.previousIndex();
}
return -1;
}
获取元素所在的位置,利用ListIterator迭代器,然后根据previousIndex获得元素所在的位置
iterator
public Iterator<E> iterator() {
return new Itr();
}
实现为返回一个Itr实现
lastIndexOf
public int lastIndexOf(Object o) {
ListIterator<E> it = listIterator(size());
if (o==null) {
while (it.hasPrevious())
if (it.previous()==null)
return it.nextIndex();
} else {
while (it.hasPrevious())
if (o.equals(it.previous()))
return it.nextIndex();
}
return -1;
}
获取元素最后出现的位置,利用ListIterator迭代器,倒叙迭代然后根据nextIndex获得位置
listIterator
- public ListIterator listIterator(final int index)
public ListIterator<E> listIterator(final int index) {
// 判断index是否复合范围
rangeCheckForAdd(index);
return new ListItr(index);
}
// 检测index是否在约束范围内
private void rangeCheckForAdd(int index) {
if (index < 0 || index > size())
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
// 绑定IndexOutOfBoundsException保存信息
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size();
}
获取从index开始的ListItr
- public ListIterator listIterator()
public ListIterator<E> listIterator() {
return listIterator(0);
}
返回一个从0开始的ListItr
subList
生成一个从fromIndex到toIndex的集合
public List<E> subList(int fromIndex, int toIndex) {
return (this instanceof RandomAccess ?
new RandomAccessSubList<>(this, fromIndex, toIndex) :
new SubList<>(this, fromIndex, toIndex));
}
class SubList<E> extends AbstractList<E> {
// 原集合
private final AbstractList<E> l;
// 偏移量
private final int offset;
//长度
private int size;
//构造函数
SubList(AbstractList<E> list, int fromIndex, int toIndex) {
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
if (toIndex > list.size())
throw new IndexOutOfBoundsException("toIndex = " + toIndex);
if (fromIndex > toIndex)
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex + ")");
l = list;
offset = fromIndex;
size = toIndex - fromIndex;
this.modCount = l.modCount;
}
// 将指定位置的元素替换成指定元素
public E set(int index, E element) {
// 下标范围检查
rangeCheck(index);
// 修改检测
checkForComodification();
// 修改下表为index和偏移量纸盒
return l.set(index+offset, element);
}
// 获取指定下标的元素
public E get(int index) {
// 下标范围检查
rangeCheck(index);
// 修改检测
checkForComodification();
return l.get(index+offset);
}
// 获取集合长度
public int size() {
// 修改检测
checkForComodification();
return size;
}
//在指定位置添加一个元素
public void add(int index, E element) {
// 下标范围检查
rangeCheckForAdd(index);
// 修改检测
checkForComodification();
// 添加元素
l.add(index+offset, element);
// 重置修改次数
this.modCount = l.modCount;
// 数组长度增加
size++;
}
// 移除指定位子元素
public E remove(int index) {
// 范围检测
rangeCheck(index);
// 修改检测
checkForComodification();
//删除元素
E result = l.remove(index+offset);
// 重置修改次数
this.modCount = l.modCount;
// 数组长度减少
size--;
return result;
}
// 范围移除
protected void removeRange(int fromIndex, int toIndex) {
// 修改检测
checkForComodification();
// 范围移除
l.removeRange(fromIndex+offset, toIndex+offset);
// 重置修改次数
this.modCount = l.modCount;
// 修改集合长度
size -= (toIndex-fromIndex);
}
// 将一个新的集合加入到集合中
public boolean addAll(Collection<? extends E> c) {
return addAll(size, c);
}
// 从某个位置加入一个新的集合
public boolean addAll(int index, Collection<? extends E> c) {
// 范围检测
rangeCheckForAdd(index);
// 新集合长度
int cSize = c.size();
if (cSize==0)
return false;
// 修改检测
checkForComodification();
// 数据加入
l.addAll(offset+index, c);
// 重置修改次数
this.modCount = l.modCount;
// 修改集合长度
size += cSize;
return true;
}
// 获取Iterator迭代器
public Iterator<E> iterator() {
return listIterator();
}
// 获取listIterator迭代器
public ListIterator<E> listIterator(final int index) {
// 修改检测
checkForComodification();
// 范围检测
rangeCheckForAdd(index);
// 返回ListIterator
return new ListIterator<E>() {
// 创建一个迭代器
private final ListIterator<E> i = l.listIterator(index+offset);
// 重写hasNext
public boolean hasNext() {
return nextIndex() < size;
}
// 重写next
public E next() {
if (hasNext())
return i.next();
else
throw new NoSuchElementException();
}
// 重写hasPrevious
public boolean hasPrevious() {
return previousIndex() >= 0;
}
// 重写previous
public E previous() {
if (hasPrevious())
return i.previous();
else
throw new NoSuchElementException();
}
// 重写nextIndex
public int nextIndex() {
return i.nextIndex() - offset;
}
// 重写previousIndex
public int previousIndex() {
return i.previousIndex() - offset;
}
// 重写remove
public void remove() {
i.remove();
SubList.this.modCount = l.modCount;
size--;
}
// 重写set
public void set(E e) {
i.set(e);
}
// 重写add
public void add(E e) {
i.add(e);
SubList.this.modCount = l.modCount;
size++;
}
};
}
// 生成子串集合
public List<E> subList(int fromIndex, int toIndex) {
return new SubList<>(this, fromIndex, toIndex);
}
// 判断下标是否超出范围
private void rangeCheck(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
// 集合下表检测
private void rangeCheckForAdd(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size;
}
// 修改检查 判断依据是当前的集合和原集合的修改次数是否一致
private void checkForComodification() {
if (this.modCount != l.modCount)
throw new ConcurrentModificationException();
}
}
// 生成
class RandomAccessSubList<E> extends SubList<E> implements RandomAccess {
RandomAccessSubList(AbstractList<E> list, int fromIndex, int toIndex) {
super(list, fromIndex, toIndex);
}
public List<E> subList(int fromIndex, int toIndex) {
return new RandomAccessSubList<>(this, fromIndex, toIndex);
}
}
未实现方法
add
在指定位置插入一个元素
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
get
获取指定位置的元素
abstract public E get(int index);
set
将指定位置重新设置成新的元素
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
结束语
注意:迭代器只有在调用next和previous才会检测ConcurrentModificationException,在调用调用hasnext之前将集合中的数据删除到size==cursor,此时hasnext返回为false,不会调用next()方法,也就不会抛出ConcurrentModificationException。