共同学习Java源代码--数据结构--AbstractList抽象类(六)

再来看这个类文件中的两个非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抽象类的源码阅读完毕。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值