再来看这个类文件中的两个非public类。
class SubList<E> extends AbstractList<E>
这个类继承自AbstractList类
private final AbstractList<E> l;
一个AbstractList类的引用,代表的是要被截取的List。
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;
}
默认修饰符修饰的构造方法,首先判断第二个参数也就是起始下标是否小于0,如果小于0则抛出异常,再判断第二个参数也就是结束下标是否大于第一个参数的尺寸,大于的话同样抛出异常,再判断如果第二个参数大于第三个参数,同样抛出异常。
然后将第一个参数赋值给成员变量I,offset变量赋值为第二个参数,size变量赋值为第二个参数和第三个参数之差,结束下标减去起始下标就是要截取的长度。本对象的modCount就是要截取的I的modCount。
public E set(int index, E element) {
rangeCheck(index);
checkForComodification();
return l.set(index+offset, element);
}
这个方法是为指定下标的元素赋值的方法,首先检查下标是否越界,然后检查是否出现并发异常。最后调用成员变量I的赋值方法去赋值并返回。
public E get(int index) {
rangeCheck(index);
checkForComodification();
return l.get(index+offset);
}
这个方法是获取指定下标的元素的方法,首先检查下标是否越界,然后检查是否出现并发异常。最后调用成员变量I的取值方法去取值并返回。
public int size() {
checkForComodification();
return size;
}
这个方法是返回本对象元素长度的方法,先检查是否出现并发异常。最后返回size变量。
public void add(int index, E element) {
rangeCheckForAdd(index);
checkForComodification();
l.add(index+offset, element);
this.modCount = l.modCount;
size++;
}
这个是添加元素的方法,首先检查下标是否越界,然后调用I的的添加方法进行添加,然后将两个modCount同步。
public E remove(int index) {
rangeCheck(index);
checkForComodification();
E result = l.remove(index+offset);
this.modCount = l.modCount;
size--;
return result;
}
这个方法是删除方法,首先检查下标是否越界,然后检查是否出现并发异常。然后调用I的删除方法进行删除。然后将两个modCount同步,然后size自减。最后返回刚删除的数据。
protected void removeRange(int fromIndex, int toIndex) {
checkForComodification();
l.removeRange(fromIndex+offset, toIndex+offset);
this.modCount = l.modCount;
size -= (toIndex-fromIndex);
}
这个方法是删除指定区间元素的方法,首先检查是否出现并发异常。然后调用I的方法删除指定区间内的元素。然后将两个modCount同步,最后减去区间长度。
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;
}
这两个方法一起看,第一个方法调用第二个方法,并将size传入第二个方法作为起始插入的下标。第二个方法首先检查第一个参数是否越界,然后获取要添加的集合的长度cSize,如果cSize为0,则直接返回false。然后检查是否出现并发异常。然后调用I的添加所有元素的方法。然后将size和cSize相加赋值给size。最后返回true。
上面三个方法的操作参数都加了offset,也就是偏移量,默认都为0。
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);
这个实现类定义了一个ListIterator变量i,有I的相关方法实现。
public boolean hasNext() {
return nextIndex() < size;
}
public E next() {
if (hasNext())
return i.next();
else
throw new NoSuchElementException();
}
public boolean hasPrevious() {
return previousIndex() >= 0;
}
public E previous() {
if (hasPrevious())
return i.previous();
else
throw new NoSuchElementException();
}
public int nextIndex() {
return i.nextIndex() - offset;
}
public int previousIndex() {
return i.previousIndex() - offset;
}
public void remove() {
i.remove();
SubList.this.modCount = l.modCount;
size--;
}
public void set(E e) {
i.set(e);
}
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);
}
这个是截取List的方法,实际上是生成一个新的对象。
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();
}
这个方法是判断是否出现并发异常的方法,判断的依据就是两个modCount是否一致。
class RandomAccessSubList<E> extends SubList<E> implements RandomAccess
这个类继承自SubList类,实现了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);
}
截取List的方法,实际上就是生成一个新的对象。
至此AbstractList抽象类的源码阅读完毕。