Java SE 是什么,包括哪些内容(二十一)?
本文内容参考自Java8标准
有序集合类(列表)承上启下的随机访问抽象类:
AbstractList
参看顺序访问抽象类:AbstractList
[https://blog.csdn.net/ruidianbaihuo/article/details/103774262]
其中加粗表示提供了实现,–表示当前接口/类中不存在这个方法。
List | AbstractCollection | AbstractList |
---|---|---|
size() | size() | – |
isEmpty() | isEmpty() | – |
contains(Object o) | contains(Object o) | – |
iterator() | iterator() | iterator() |
toArray() | toArray() | – |
toArray(T[] a) | toArray(T[] a) | – |
– | finishToArray(T[] r, Iterator<?> it) | – |
– | hugeCapacity(int minCapacity) | – |
add(E e) | add(E e) | add(E e) |
remove(Object o) | remove(Object o) | – |
containsAll(Collection<?> c) | containsAll(Collection<?> c) | – |
addAll(Collection<? extends E> c) | addAll(Collection<? extends E> c) | – |
addAll(int index, Collection<? extends E> c) | – | addAll(int index, Collection<? extends E> c) |
removeAll(Collection<?> c) | removeAll(Collection<?> c) | – |
retainAll(Collection<?> c) | retainAll(Collection<?> c) | – |
replaceAll(UnaryOperator< E > operator) | – | – |
sort(Comparator<? super E> c) | – | – |
clear() | clear() | clear() |
equals(Object o) | – | equals(Object o) |
hashCode() | – | hashCode() |
get(int index) | – | get(int index) |
set(int index, E element) | – | set(int index, E element) |
add(int index, E element) | – | add(int index, E element) |
remove(int index) | – | remove(int index) |
indexOf(Object o) | – | indexOf(Object o) |
lastIndexOf(Object o) | – | lastIndexOf(Object o) |
listIterator() | – | listIterator() |
listIterator(int index) | – | listIterator(final int index) |
subList(int fromIndex, int toIndex) | – | subList(int fromIndex, int toIndex) |
spliterator() | – | – |
– | toString() | – |
– | – | rangeCheckForAdd(int index) |
– | – | outOfBoundsMsg(int index) |
– | – | removeRange(int fromIndex, int toIndex) |
类声明:
public abstract class AbstractList<E> extends
AbstractCollection<E> implements List<E>
源代码图示(图下面有解释说明):
英文注释分别阐述了以下内容(一个段落用一个小标):
⑴、抽象类AbstractList提供了接口List的基本实现,它代表了随机访问(它的底层数据结构是数组,数组能随机访问)。如果需要实现顺序访问,应该使用抽象类AbstractSequentialList(它的底层数据结构是链表,链表中的元素只能一个接着一个访问)。
⑵、如果想实现一个不可修改的列表,只需要扩展抽象类AbstractList并为方法get(int index)和方法size()提供实现。
⑶、如果想实现一个可修改的列表,需要重写方法set(int index, E element),否则会引发UnsupportedOperationException异常。如果想实现一个大小可变的列表,需要重写方法add(int index, E element)和方法remove(int index)。
⑷、根据接口Collection规范中的建议,抽象类AbstractList应该提供一个不带任何形式参数的构造函数。
⑸、不必为抽象类AbstractList提供迭代器的实现,因为它的底层数据结构是数组,数组不需要迭代器,单纯通过索引就可以实现随机访问。
⑹、抽象类AbstractList中的每个非抽象方法的实现在文档中都有详细描述。如果有更有效的实现,可以直接进行覆盖。
⑺、抽象类AbstractList是Java Collections Framework中的重要一员。
1、AbstractList()
//protected修饰表示仅提供给子类继承使用,不对外公开
//它是抽象类AbstractList唯一的构造方法
protected AbstractList() {
}
2、modCount
//记录当前List结构修改的次数
//结构修改指:更改当前List的大小(添加或删除元素)
//或其它方式导致正在进行的迭代可能返回错误的结果
//初始化值为0,该变量供实现迭代器和列表迭代器的使用
//如果它的值在迭代过程中被更改则抛出
//ConcurrentModificationException异常
//所以在以下方法的开始处都会判断这个变量的值是否改变
//next(),remove(),previous(),set(),add()
//它为迭代过程中的并发修改提供了快速故障行为(快速失败机制)
protected transient int modCount = 0;
3、add(E e)
//将指定元素e添加到当前List的末尾
public boolean add(E e) {
//调用方法add(int index,E element)
//size()表示新元素的索引值
add(size(), e);
return true;
}
4、get(int index)
//返回指定索引位置index的元素
//抽象方法,待子类实现
abstract public E get(int index);
5、set(int index, E element)
//用指定元素element替换当前List指定索引位置index的元素
//并将被替换的元素返回,如果索引位置index没有元素
//则直接添加元素element
public E set(int index, E element) {
//没有提供实现,只规定了可能会
//抛出UnsupportedOperationException异常
throw new UnsupportedOperationException();
}
4、add(int index, E element)
//将指定元素element添加到当前List的指定索引位置index
public void add(int index, E element) {
//没有提供实现,只规定了可能会
//抛出UnsupportedOperationException异常
throw new UnsupportedOperationException();
}
5、remove(int index);
//删除当前List指定索引位置index的元素并返回
public E remove(int index) {
//没有提供实现,只规定了可能会
//抛出UnsupportedOperationException异常
throw new UnsupportedOperationException();
}
6、indexOf(Object o);
//返回指定元素o在当前List首次出现的索引值
public int indexOf(Object o) {
//获取列表迭代器
ListIterator<E> it = listIterator();
//判断指定元素o==null和o!=null的情况
if (o==null) {
//循环遍历当前List
//it.hasNext()的结果类型为boolean,表示当前List是否
//还有可供访问的后一个元素
while (it.hasNext())
//it.next()返回列表迭代器的游标指向的元素
if (it.next()==null)
//返回列表迭代器的游标指向的元素的
//前一个元素的索引值,这里先调用了方法next()
//如果观察足够仔细,就能发现方法next()
//的实现末尾都会将游标值+1
//表示指向后一个元素,再结合方法previousIndex()
//的实现,就能明白为什么是it.previousIndex()
return it.previousIndex();
//o!=null
} else {
while (it.hasNext())
//如果指定元素o与迭代器的游标指向的元素相等
if (o.equals(it.next()))
//注意,这里也同样先调用了方法next()
return it.previousIndex();
}
//如果以上情况都不符,说明当前列表对象不包含指定元素
//o,直接返回-1
return -1;
}
看完了方法indexOf(Object o)的实现,相信也可以猜出方法lastIndexOf(Object o)的实现,只不过它是倒序。
7、lastIndexOf(Object o);
//返回指定元素o在当前List最后一次出现的索引值
public int lastIndexOf(Object o) {
ListIterator<E> it = listIterator(size());
if (o==null) {
//从当前List的末尾开始循环,所以需要判断是否
//还有前一个元素可供访问,单词Previous和单词Next是对应的
while (it.hasPrevious())
//it.previous()返回列表迭代器的游标指向的元素
if (it.previous()==null)
//返回列表迭代器的游标指向的元素的
//前一个元素的索引值,这里先调用了方法previous()
//如果观察足够仔细,就能发现方法previous()
//的实现末尾都会将游标值-1
//表示指向前一个元素,再结合方法nextIndex()
//的实现,就能明白为什么是it.nextIndex()
return it.