【集合类】源码解析之 List接口、AbstractList抽象类

List接口

存取顺序一致,有索引,允许重复

类声明

public interface List<E> extends Collection<E> 

特有方法

所有通过索引操作的方法都要注意其索引的范围,否则容易导致发生 IndexOutOfBoundsException

void add(int index, E element); // 向指定索引处增加元素 0 <= index <= size
boolean addAll(int index, Collection<? extends E> c); // 向指定索引处增加集合中的所有元素 0 <= index <= size
E remove(int index); // 删除指定索引位置的元素 0 <= index < size
E set(int index, E element); // 修改指定索引处的元素 0 <= index < size
E get(int index); // 获取指定索引处的元素 0 <= index < size
int indexOf(Object o); // 获取指定元素第一次出现的索引,若不存在则返回-1
int lastIndexOf(Object o); // 获取指定元素最后一次出现的索引,若不存在则返回-1
List<E> subList(int fromIndex, int toIndex); // 返回集合中从fromIndex(含)到toIndex(不含)的视图,与原集合会相互影响
ListIterator<E> listIterator(); // 返回listIterator hasPrevious()、previous()、add(E e);
ListIterator<E> listIterator(int index); // 从指定索引处开始返回listIterator 0 <= index <= size
// jdk1.8新增方法
default void sort(Comparator<? super E> c){} // 根据Comparator来排序数组
default void replaceAll(UnaryOperator<E> operator) {} // 将该列表的每个元素替换为该运算符应用于该元素的结果

AbstractList抽象类

实现了 List 的部分方法,iteratorsize 没有实现

类声明

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>

主要字段

// 维护了集合被修改的次数
protected transient int modCount = 0;

方法实现

// 唯一的构造函数
protected AbstractList() {}
// 限定了add、set、remove操作, 由子类实现
public void add(int index, E element) { throw new UnsupportedOperationException();}
public E set(int index, E element) { throw new UnsupportedOperationException();}
public E remove(int index) { throw new UnsupportedOperationException();}

// 获取指定角标的元素,未实现
abstract public E get(int index);

// 从前往后找,获取指定元素在集合中第一次出现的索引,若不存在则返回-1
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;
}

// 从后往前找,获取指定元素在集合中第一次出现的索引,若不存在则返回-1
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;
}

// 在集合末尾添加元素, add由子类实现
public boolean add(E e) {
    add(size(), e);
    return true;
}

// 向指定索引处增加集合中的所有元素, add由子类实现
public boolean addAll(int index, Collection<? extends E> c) {
    // 索引检查 index < 0 || index > size()
    rangeCheckForAdd(index);
    boolean modified = false;
    for (E e : c) {
        add(index++, e);
        modified = true;
    }
    return modified;
}

// 范围删除,包含 fromIndex,不包含 toIndex
protected void removeRange(int fromIndex, int toIndex) {
    ListIterator<E> it = listIterator(fromIndex);
    for (int i=0, n=toIndex-fromIndex; i<n; i++) {
        it.next();
        it.remove();
    }
}

// 调用 removeRange
public void clear() {
    removeRange(0, size());
}

// 获取迭代器
public Iterator<E> iterator() {
    return new Itr();
}

// 获取list迭代器
public ListIterator<E> listIterator() {
    return listIterator(0);
}

// 从指定索引获取迭代器
public ListIterator<E> listIterator(final int index) {
    // 索引检查 index < 0 || index > size()
    rangeCheckForAdd(index);
    return new ListItr(index);
}

// 截取集合,返回的集合与原集合相互影响
public List<E> subList(int fromIndex, int toIndex) {
    return (this instanceof RandomAccess ?
            new RandomAccessSubList<>(this, fromIndex, toIndex) :
            new SubList<>(this, fromIndex, toIndex));
}

// 两个个内部类
private class Itr implements Iterator<E> {}
private class ListItr extends Itr implements ListIterator<E> {}
// 在AbstractList类下的两个类,**不是内部类
class SubList<E> extends AbstractList<E> {}
class RandomAccessSubList<E> extends SubList<E> implements RandomAccess {}

内部类 Itr

AbstractList通过使用两个内部类 ItrListItr 实现集合的遍历

private class Itr implements Iterator<E> {
        // 用来标识当前所要遍历元素的下标
        int cursor = 0;

        // 用来记录调用next调用后所指向的下标,调用remove后会重置为-1
        int lastRet = -1;

       	// 用来标识最初的modCount(来至于外部类AbstractList),调用迭代器的修改方法会重新赋值
        int expectedModCount = modCount;

    	// 每次遍历时add/remove都会修改modCount,若检测到expectedModCount和modCount不一致就会抛异常
    	final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    	
    	// 判断是否有下一个元素
        public boolean hasNext() {
            return cursor != size();
        }

    	// 获取下一个元素,先检测modCount是否被修改,获取元素,修改lastRet和cursor
        public E next() {
            checkForComodification();
            try {
                int i = cursor;
                E next = get(i);
                lastRet = i;
                cursor = i + 1;
                return next;
            } catch (IndexOutOfBoundsException e) {
                checkForComodification();
                throw new NoSuchElementException();
            }
        }

    	// 删除元素,删除前必须调用next()方法,删除的是当前元素也就是角标为lastRet的元素
        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                // 调用子类实现的remove方法删除元素,并给cursor、lastRet和expectedModCount重新赋值
                AbstractList.this.remove(lastRet);
                if (lastRet < cursor)
                    cursor--;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException e) {
                throw new ConcurrentModificationException();
            }
        }
    }

内部类 ListItr

ListItr 继承了 Itr 实现了 ListIteratorListIterator 接口是对 Iterator 的扩展,使迭代器不仅能向后迭代也能向前迭代,还能获取当前元素和将要遍历元素的下标,也可对元素进行增、删、改操作

private class ListItr extends Itr implements ListIterator<E> {
        ListItr(int index) {
            cursor = index;
        }

    	// 是否有前一个元素
        public boolean hasPrevious() {
            return cursor != 0;
        }

    	// 获取前一个元素并修改cursor和lastRet
        public E previous() {
            checkForComodification();
            try {
                int i = cursor - 1;
                E previous = get(i);
                lastRet = cursor = i;
                return previous;
            } catch (IndexOutOfBoundsException e) {
                checkForComodification();
                throw new NoSuchElementException();
            }
        }
		
    	// 获取下一个将要迭代的元素角标
        public int nextIndex() {
            return cursor;
        }

    	// 获取当前元素的角标
        public int previousIndex() {
            return cursor-1;
        }

    	// 调用子类实现的set方法修改元素并给并给expectedModCount重新赋值
        public void set(E e) {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                AbstractList.this.set(lastRet, e);
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
        // 调用子类实现的add方法修改元素并给并给cursor、lastRet和expectedModCount重新赋值
        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();
            }
        }
    }

SubList

SubList 调用subList方法所创建的对象,所引用的还是原数组

class SubList<E> extends AbstractList<E> {
    // 用于存放原List的引用
    private final AbstractList<E> l;
    // 子List在原List中的开始位置
    private final int offset;
    // 子List的大小
    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;
    }
    
    // 下标检测
    private void rangeCheck(int index) {
        if (index < 0 || index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
    // add下标检测
    private void rangeCheckForAdd(int index) {
        if (index < 0 || index > size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
    
    // 修改检测,判断原集合中的modCount和SubList中的modCount是否相等
    private void checkForComodification() {
        if (this.modCount != l.modCount)
            throw new ConcurrentModificationException();
    }

	// 调用原集合的set方法 offset+index
    public E set(int index, E element) {
        rangeCheck(index);
        checkForComodification();
        return l.set(index+offset, element);
    }

    // 调用原集合的get方法 offset+index
    public E get(int index) {
        rangeCheck(index);
        checkForComodification();
        return l.get(index+offset);
    }

    // 子集合的大小
    public int size() {
        checkForComodification();
        return size;
    }

    // 调用原集合的add方法 offset+index,并修改this.mod和size
    public void add(int index, E element) {
        rangeCheckForAdd(index);
        checkForComodification();
        l.add(index+offset, element);
        this.modCount = l.modCount;
        size++;
    }

    // 调用原集合的remove方法 offset+index,并修改this.mod和size
    public E remove(int index) {
        rangeCheck(index);
        checkForComodification();
        E result = l.remove(index+offset);
        this.modCount = l.modCount;
        size--;
        return result;
    }

    // 调用原集合的removeRange方法
    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;
    }

    public Iterator<E> iterator() {
        return listIterator();
    }

    public ListIterator<E> listIterator(final int index) {
        checkForComodification();
        rangeCheckForAdd(index);
		// 匿名内部类 对ListIterator实现
        return new ListIterator<E>() {
            // ...
        };
    }

    // 套娃subList
    public List<E> subList(int fromIndex, int toIndex) {
        return new SubList<>(this, fromIndex, toIndex);
    }

    // 异常消息
    private String outOfBoundsMsg(int index) {
        return "Index: "+index+", Size: "+size;
    }
}

RandomAccessSubList

RandomAccess 是一个标记接口,表明实现这个接口的 List 集合是支持快速随机访问,使用for循环遍历效率会高于迭代器遍历

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);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章