Java的ArrayList源码解析(中级Java工程师面试必备,详细注释全部实现方法,内部类与变量)

介绍

参看Java8中ArrayList源码(不包括继承父类的)包含47个方法(method)、4个内部类(inner class)和7个定义的变量(field),在基础增删改查操作外,含有更多丰富的高级操作,为开发者访问链表结构中元素提供方便。下面一一在源码中注释说明。

47个方法

内部类和变量讲解包括在方法的讲解中,因为无论内部类还是变量定义都是被用于方法中,换言之,在方法实现需要的前提下才定义内部类和变量。

3个构造函数

ArrayList具有三个构造函数,分别是设置初始容量、默认是空链表和传入另外一个集合元素初始化链表。
两个难点:
1.EMPTY_ELEMENTDATA与DEFAULTCAPACITY_EMPTY_ELEMENTDATA区别,注释中会说明清楚
2.数组协变性,简单说就是在编译期间和运行期间数组的类型可能不一致。任意类型T的数组都可以赋值给Object数组,之后作为Object数组进行操作。可是本质上仍就是类型T的数组,当向数组中添加不可以转化为T类型的数据时,弹出异常ArrayStoreException。

/**
    为避免多次创建0容量的空数组,因此设置静态变量EMPTY_ELEMENTDATA和DEFAULTCAPACITY_EMPTY_ELEMENTDATA。当链表创建是为空链表时,elementData指向它们。两者用于区分空链表是默认初始值为空表的还是人工手动设置为空表的。-1
*/
private static final Object[] EMPTY_ELEMENTDATA = {};//EMPTY_ELEMENTDATA用于标记空链表是被人工手动设置为0容量的,与默认生成时使用DEFAULTCAPACITY_EMPTY_ELEMENTDATA区分

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//DEFAULTCAPACITY_EMPTY_ELEMENTDATA标记空链表是默认生成的,而非人工手动设置的

transient Object[] elementData; //因为数组是协变,在泛型编程中使用Object数组存储泛型

private int size;//链表元素个数

public ArrayList(int initialCapacity) {//初始化数组的大小
    if (initialCapacity > 0) {
        this.elementData = new Object[initialCapacity];//初始化initialCapacity容量的Object数组
    } else if (initialCapacity == 0) {//如果工人手动初始化为空链表,赋值elementData为EMPTY_ELEMENTDATA
        this.elementData = EMPTY_ELEMENTDATA;
    } else {//否则initialCapacity为负数时抛出非法参数异常
        throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
    }
}
public ArrayList() {//默认初始化链表为空链表,默认使用静态变量DEFAULTCAPACITY_EMPTY_ELEMENTDATA
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
 }

public ArrayList(Collection<? extends E> c) {//传入一个集合结构
    elementData = c.toArray();//转化为数组赋值给elementData
    if ((size = elementData.length) != 0) {//elementData元素,将总数赋值size变量
        //如果赋值之后的elementData不是Object[]类型,此时需要进行类型转化为Object[]类型。之所以c.toArray()执行后不是Object[]类型,这与数组协变性有关。-2
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, size, Object[].class);
     } else {
         // elementData没有元素,elementData设置为空数组
         this.elementData = EMPTY_ELEMENTDATA;
     }
}

32个操作队列的函数

缩减容量
变量size记录队列当前具有的元素个数,而Object数组elementData的长度是初始化和之后扩容确定的,大于等于size的值。函数trimToSize将数组elementData的长度缩减至size,最小化数组的存储空间。

protected transient int modCount = 0;//继承自父类AbstractList,记录链表被修改的次数

public void trimToSize() {
    modCount++;//修改次数加1
    if (size < elementData.length) {//如果size小于数据长度
    //size为0时,设置为手动标记的空数组;否则复制size大小的数组并且赋值给elementData
        elementData = (size == 0) ? EMPTY_ELEMENTDATA : Arrays.copyOf(elementData, size);
    }
}

扩容函数
两个重点:保证尽可能少的进行扩容操作,减少性能消耗。
1.如果当前Object数组为默认空数组DEFAULTCAPACITY_EMPTY_ELEMENTDATA,初始化最小值为DEFAULT_CAPACITY。
2.扩容grow操作,默认扩容公式newCapacity = oldCapacity + (oldCapacity >> 1),保证扩容的容量在整型范围内至少为这个数值。

private static final int DEFAULT_CAPACITY = 10;//默认队列长度10

public void ensureCapacity(int minCapacity) {
    //如果是默认的空数组,队列长度设置为默认值10;否则设置0
    int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) 
        ? 0 : DEFAULT_CAPACITY;
    if (minCapacity > minExpand) {
        ensureExplicitCapacity(minCapacity);
    }
}

private void ensureCapacityInternal(int minCapacity) {
    //内部方法,如果数组是默认空数组,则选取设置值minCapacity与默认值中更大的那个值
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    //设置列表大小为minCapacity
    ensureExplicitCapacity(minCapacity);
}

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;//修改次数加1
    //当设置值minCapacity大于当前数组大小时,扩容
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;//数组最大值

private void grow(int minCapacity) {
    //elementData原始大小
    int oldCapacity = elementData.length;
    //elementData默认扩容新的大小为原始值的1.5倍,默认扩容值
    int newCapacity = oldCapacity + (oldCapacity >> 1);
   //默认扩容值和传入的容量值选择大的那个数作为新的容量值
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    //扩容新值如果超过数组设置最大值,调用hugeCapacity函数
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity);
}

private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    //如果超过数组最大值MAX_ARRAY_SIZE,设置为最大整型值;否则使数组最大值MAX_ARRAY_SIZE
    return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}

容量相关函数

public int size() {//返回当前链表具有的元素个数
    return size;
}
public boolean isEmpty() {//判断size为0时,证明此链表为空
    return size == 0;
}

索引相关操作

public boolean contains(Object o) {
    //判断链表中是否包含元素o,调用indexOf方法
    return indexOf(o) >= 0;
}
public int indexOf(Object o) {
    if (o == null) {//如果o为null,遍历数组如果存在null元素,返回第一个null元素的索引
        for (int i = 0; i < size; i++)
            if (elementData[i]==null)
                return i;
    } else {//遍历数组查找是否有与元素o相等的元素,如果存在返回第一个找到元素的索引
        for (int i = 0; i < size; i++)
            if (o.equals(elementData[i]))
                return i;
    }
    //未找到返回-1
    return -1;
}
public int lastIndexOf(Object o) {//与方法indexOf相反,从后往前遍历数组找到元素o的最后一个位置索引
    if (o == null) {
        for (int i = size-1; i >= 0; i--)
            if (elementData[i]==null)
                return i;
    } else {
        for (int i = size-1; i >= 0; i--)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;
}

复制函数

public Object clone() {
    try {//返回当前链表对象的浅拷贝
        ArrayList<?> v = (ArrayList<?>) super.clone();
        v.elementData = Arrays.copyOf(elementData, size);
        v.modCount = 0;
        return v;
    } catch (CloneNotSupportedException e) {
        // this shouldn't happen, since we are Cloneable
         throw new InternalError(e);
    }
}

转化数组函数

public Object[] toArray() {//创建并返回一个包含链表中所有元素的数组
    //需要分配空间产生一个新的数组
    return Arrays.copyOf(elementData, size);
}
public <T> T[] toArray(T[] a) {
    if (a.length < size)//如果传入的数组a长度小于当前列表元素个数,创建一个新数组返回
        // Make a new array of a's runtime type, but my contents:
        return (T[]) Arrays.copyOf(elementData, size, a.getClass());
    System.arraycopy(elementData, 0, a, 0, size);//将当前列表元素复制到a数组中
    if (a.length > size)//如果a数组长度大于size,a[size]置null
        a[size] = null;
    return a;//返回a数组
}

增删改查操作函数

E elementData(int index) {//根据索引index返回数组中的元素
    return (E) elementData[index];
}
public E set(int index, E element) {//对索引index位置设置值element
    rangeCheck(index);
    E oldValue = elementData(index);//获取设置之前的值,旧值
    elementData[index] = element;//设置新值
    return oldValue;//返回旧值
}
public E get(int index) {//返回索引index的元素
    rangeCheck(index);
    return elementData(index);
}
private void rangeCheck(int index) {//如果查找索引index大于当前列表元素个数size,返回越界异常
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private String outOfBoundsMsg(int index) {//构建越界异常的错误信息
    return "Index: "+index+", Size: "+size;
}
public boolean add(E e) {//增加元素e在链表结尾
    //修改遍历modCount增加1,并且如果数组容量不够执行扩容
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;//size位置赋值e,size自增1
    return true;
}
public void add(int index, E element) {//增加元素e在链表指定位置index
    rangeCheckForAdd(index);
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    //从index起将数组元素后移一位,例如index处元素复制到index+1处,以此类推
    System.arraycopy(elementData, index, elementData, index + 1, size - index);
    elementData[index] = element;//index位置赋值e
    size++;
}
private void rangeCheckForAdd(int index) {//增加校验索引正确性
    if (index > size || index < 0)//如果index大于size或者小于0,返回越界异常
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
public E remove(int index) {
    rangeCheck(index);
    modCount++;
    E oldValue = elementData(index);//获取要删除的元素
    int numMoved = size - index - 1;//统计将要移动的元素
    if (numMoved > 0)
        //从index+1起之后的元素依次前移一位
        System.arraycopy(elementData, index+1, elementData, index, numMoved);
    //size位置置null并且减1,GC回收原来的元素
    elementData[--size] = null; // clear to let GC do its work
    return oldValue;//返回删除的元素
}
public boolean remove(Object o) {
    if (o == null) {
        for (int index = 0; index < size; index++)//从前向后遍历数组找到第一个null元素
            if (elementData[index] == null) {
                fastRemove(index);//执行删除逻辑
                return true;
            }
     } else {
         for (int index = 0; index < size; index++)
             if (o.equals(elementData[index])) {//从前向后遍历数组找到第一个元素o
                 fastRemove(index);//执行删除逻辑
                 return true;
             }
     }
     return false;
}
private void fastRemove(int index) {
    modCount++;
    int numMoved = size - index - 1;//确定需要移动的元素个数
    if (numMoved > 0)
        //从index+1起每个元素依次前移一位
        System.arraycopy(elementData, index+1, elementData, index, numMoved);
    elementData[--size] = null; // clear to let GC do its work
}
public void clear() {//清空链表
    modCount++;
    // clear to let GC do its work
    for (int i = 0; i < size; i++)//数组中所有元素置null
        elementData[i] = null;
    size = 0;//元素个数size设置为0
}
public boolean addAll(Collection<? extends E> c) {//集合c的元素增加到链表的尾部
    Object[] a = c.toArray();//集合c转化数组
    int numNew = a.length;
    ensureCapacityInternal(size + numNew);  // Increments modCount
    System.arraycopy(a, 0, elementData, size, numNew);//数组elementData的size索引起,集合c的元素依次复制
    size += numNew;//更新size
    return numNew != 0;//如果增加的元素个数不为0,返回true
}
public boolean addAll(int index, Collection<? extends E> c) {//集合c的元素插入到链表索引index位置
    rangeCheckForAdd(index);
    Object[] a = c.toArray();//集合c转化数组
    int numNew = a.length;
    ensureCapacityInternal(size + numNew);  // Increments modCount
    int numMoved = size - index;
    if (numMoved > 0)
        //从index位置数组elementData元素后移numNew位
        System.arraycopy(elementData, index, elementData, index + numNew, numMoved);
    System.arraycopy(a, 0, elementData, index, numNew);//集合c元素填补到链表index和index + numNew之间
    size += numNew;//更新size
    return numNew != 0;//如果增加的元素个数不为0,返回true
}
protected void removeRange(int fromIndex, int toIndex) {
    modCount++;
    int numMoved = size - toIndex;//需要移动的元素个数
    //toIndex之后元素前移到fromIndex
    System.arraycopy(elementData, toIndex, elementData, fromIndex, numMoved);
    // clear to let GC do its work
    int newSize = size - (toIndex-fromIndex);
    for (int i = newSize; i < size; i++) {//多余元素置null
        elementData[i] = null;
    }
    size = newSize;
}
public boolean removeAll(Collection<?> c) {//删除链表中集合c的元素
    Objects.requireNonNull(c);
    return batchRemove(c, false);
}
public boolean retainAll(Collection<?> c) {//保留链表中集合c的元素
    Objects.requireNonNull(c);
    return batchRemove(c, true);
}
private boolean batchRemove(Collection<?> c, boolean complement) {//complement为true表示保留集合c中元素,为false表示要删除集合c中元素
    final Object[] elementData = this.elementData;
    int r = 0, w = 0;
    boolean modified = false;
    try {
        for (; r < size; r++)
            if (c.contains(elementData[r]) == complement)//complement为true时保留集合c元素,complement为false时删除集合c元素
                elementData[w++] = elementData[r];
    } finally {
        // Preserve behavioral compatibility with AbstractCollection,
        // even if c.contains() throws.
         if (r != size) {//r不等于size时,没有完全遍历链表,处理兼容性
             System.arraycopy(elementData, r, elementData, w, size - r);
             w += size - r;
         }
        if (w != size) {//当w!=size,链表有删减。链表中有w个元素
            // clear to let GC do its work
            for (int i = w; i < size; i++)
                elementData[i] = null;
            modCount += size - w;
            size = w;
            modified = true;
        }
}
    return modified;
}

IO流操作

private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{
    // Write out element count, and any hidden stuff
    int expectedModCount = modCount;
    s.defaultWriteObject();
    // Write out size as capacity for behavioural compatibility with clone()
    s.writeInt(size);
    // Write out all elements in the proper order.
    for (int i=0; i<size; i++) {
        s.writeObject(elementData[i]);//读取链表元素到输出流
    }
    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }
}
private void readObject(java.io.ObjectInputStream s) 
    throws java.io.IOException, ClassNotFoundException {
    elementData = EMPTY_ELEMENTDATA;
    // Read in size, and any hidden stuff
    s.defaultReadObject();
    // Read in capacity
    s.readInt(); // ignored
    if (size > 0) {
        // be like clone(), allocate array based upon size not capacity
        ensureCapacityInternal(size);
        Object[] a = elementData;
        // Read in all elements in the proper order.
        for (int i=0; i<size; i++) {
            a[i] = s.readObject();//从输入流读取元素写入链表中
        }
    }
}

迭代器

Java的链表提供迭代器功能,迭代器基于迭代器模式设计,在遍历数据操作中广泛使用。用户代码调用操作迭代器即可,对底层数据结构不用关心,换言之迭代器让底层具体实现对用户不可知。

public ListIterator<E> listIterator(int index) {//生成一个指向index位置元素的链表迭代器
    if (index < 0 || index > size)
        throw new IndexOutOfBoundsException("Index: "+index);
    return new ListItr(index);
}
public ListIterator<E> listIterator() {//生成一个链表特有的迭代,相当于对链表定制的迭代器,有一些链表特殊的操作
    return new ListItr(0);
}
public Iterator<E> iterator() {//生成一个通用的迭代器,实现的是迭代器的基本操作
    return new Itr();
}
private class Itr implements Iterator<E> {
    int cursor;       // index of next element to return 下一个元素的索引位置
    int lastRet = -1; // index of last element returned; -1 if no such 上一次返回元素的索引位置,如果没有返回元素则为-1
    int expectedModCount = modCount;
    public boolean hasNext() {//是否有下一个元素,因为cursor为下一个元素的索引位置,所以只要其不等于链表的元素总个数,则证明尚未遍历完全
        return cursor != size;
    }
    @SuppressWarnings("unchecked")
    public E next() {//返回下一个元素
        //遍历之前首先确认是否有其他线程修改过链表,如果已经改变则弹出异常ConcurrentModificationException
        checkForComodification();
        int i = cursor;//i指向要遍历的下一个元素
        //如果i超过了链表的size会弹出异常,这就是为什么好多资料讲到在使用迭代器时要先调用hasNext()函数,再使用next()遍历,以免产生异常NoSuchElementException()
        if (i >= size)
            throw new NoSuchElementException();
        Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length)
            throw new ConcurrentModificationException();
        cursor = i + 1;//cursor指向之后的元素
        return (E) elementData[lastRet = i];//返回i所在元素,并且lastRet置为i表示上一次访问的元素位置
    }
    public void remove() {
        if (lastRet < 0)
            throw new IllegalStateException();
        checkForComodification();
        try {
            ArrayList.this.remove(lastRet);//删除上一次访问到的元素
            //cursor已到删除元素所在索引,这样在这条线程中仍旧可以使用迭代器继续遍历
            cursor = lastRet;
            lastRet = -1;
            expectedModCount = modCount;
        } catch (IndexOutOfBoundsException ex) {
            throw new ConcurrentModificationException();
        }
    }
    @Override
    @SuppressWarnings("unchecked")
    public void forEachRemaining(Consumer<? super E> consumer) {//Java8新增功能,利用Consumer定义的功能对链表的每个元素进行特定的操作
        Objects.requireNonNull(consumer);
        final int size = ArrayList.this.size;
        int i = cursor;
        if (i >= size) {
            return;
        }
        final Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length) {
            throw new ConcurrentModificationException();
        }
        while (i != size && modCount == expectedModCount) {
            consumer.accept((E) elementData[i++]);//利用Consumer定义的功能对链表的每个元素进行特定的操作
        }
        // update once at end of iteration to reduce heap write traffic
        cursor = i;
        lastRet = i - 1;
        checkForComodification();
    }
    final void checkForComodification() {//检查是否有其他线程修改链表
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
    }
}
private class ListItr extends Itr implements ListIterator<E> {//继承Itr实现链表一些特定功能
    ListItr(int index) {
        super();
        cursor = index;
    }
    public boolean hasPrevious() {//是否有前一个元素
        return cursor != 0;
    }
    public int nextIndex() {//下一个元素的索引位置
        return cursor;
    }
    public int previousIndex() {//上一个元素的索引位置
        return cursor - 1;
    }
    @SuppressWarnings("unchecked")
    public E previous() {//返回前一个元素
        checkForComodification();
        int i = cursor - 1;//cursor表示下一个元素索引,减1即是前一个元素的索引
        if (i < 0)
            throw new NoSuchElementException();
        Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length)
            throw new ConcurrentModificationException();
        cursor = i;
        return (E) elementData[lastRet = i];
    }
    public void set(E e) {//将上一次访问的元素设置为e
        if (lastRet < 0)
            throw new IllegalStateException();
        checkForComodification();
        try {
            ArrayList.this.set(lastRet, e);
         } catch (IndexOutOfBoundsException ex) {
             throw new ConcurrentModificationException();
        }
    }
    public void add(E e) {//增加元素e到当前游标cursor位置
        checkForComodification();
        try {
            int i = cursor;
            ArrayList.this.add(i, e);
            cursor = i + 1;
            lastRet = -1;
            expectedModCount = modCount;
         } catch (IndexOutOfBoundsException ex) {
             throw new ConcurrentModificationException();
         }
    }
}

子链表操作

链表的利用函数subList生成链表中一段元素的视图对象SubList,Java不会新分配空间,对象SubList任何操作都会影响到链表中元素,例如修改SubList对象中元素,原来链表中元素也会被修改。类SubList设计类似于虚拟机类加载的双亲委派模型,传入SubList中当前链表引用,所以操作直接作用于当前链表。

public List<E> subList(int fromIndex, int toIndex) {//函数创建类SubList对象,是当前链表部分元素的视图
    subListRangeCheck(fromIndex, toIndex, size);
    return new SubList(this, 0, fromIndex, toIndex);
}
static void subListRangeCheck(int fromIndex, int toIndex, int size) {//校验传入的索引参数是否正确
    if (fromIndex < 0)
        throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
    if (toIndex > size)
        throw new IndexOutOfBoundsException("toIndex = " + toIndex);
    if (fromIndex > toIndex)
        throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
}
private class SubList extends AbstractList<E> implements RandomAccess {
    private final AbstractList<E> parent;//类似于虚拟机类加载的双亲委派模型,传入SubList中当前链表引用
    private final int parentOffset;//操作链表parent时使用
    private final int offset;//操作链表elementData时使用
    int size;
    SubList(AbstractList<E> parent, int offset, int fromIndex, int toIndex) {
        this.parent = parent;
        this.parentOffset = fromIndex;
        this.offset = offset + fromIndex;
        this.size = toIndex - fromIndex;
        this.modCount = ArrayList.this.modCount;
    }
    public E set(int index, E e) {
        rangeCheck(index);
        checkForComodification();
        E oldValue = ArrayList.this.elementData(offset + index);
        ArrayList.this.elementData[offset + index] = e;//offset起始设置第index元素为e
        return oldValue;
    }
    public E get(int index) {
        rangeCheck(index);
        checkForComodification();
        return ArrayList.this.elementData(offset + index);//offset起始获取第index元素
    }
    public int size() {
        checkForComodification();
        return this.size;//返回子链表的元素个数
    }
    public void add(int index, E e) {
        rangeCheckForAdd(index);
        checkForComodification();
        parent.add(parentOffset + index, e);//parentOffset起始添加元素e到第index索引位置
        this.modCount = parent.modCount;
        this.size++;
    }
    public E remove(int index) {
        rangeCheck(index);
        checkForComodification();
        E result = parent.remove(parentOffset + index);//parentOffset起始删除第index元素
        this.modCount = parent.modCount;
        this.size--;
        return result;
    }
    protected void removeRange(int fromIndex, int toIndex) {
        checkForComodification();
        parent.removeRange(parentOffset + fromIndex, parentOffset + toIndex);//parentOffset起始删除fromIndex到toIndex区间元素
        this.modCount = parent.modCount;
        this.size -= toIndex - fromIndex;
    }
    public boolean addAll(Collection<? extends E> c) {
        return addAll(this.size, c);
    }
    public boolean addAll(int index, Collection<? extends E> c) {
        rangeCheckForAdd(index);
        int cSize = c.size();
        if (cSize==0)
            return false;
        checkForComodification();
        parent.addAll(parentOffset + index, c);//parentOffset起始从index将集合c中元素添加到链表中
        this.modCount = parent.modCount;
        this.size += cSize;//同时子链表size值也增加
        return true;
    }
    public Iterator<E> iterator() {//生成子链表的迭代器
        return listIterator();
    }
    public ListIterator<E> listIterator(final int index) {//迭代器操作与之前注释讲解的链表的迭代器功能一致,不赘述
        checkForComodification();
        rangeCheckForAdd(index);
        final int offset = this.offset;
        return new ListIterator<E>() {//生成一个实现接口ListIterator的匿名类对象
            int cursor = index;
            int lastRet = -1;
            int expectedModCount = ArrayList.this.modCount;
            //实现方法不再罗列...,有需要可以直接查看源码
        }
    public List<E> subList(int fromIndex, int toIndex) {//传入当前列表生成子列表的子列表
        subListRangeCheck(fromIndex, toIndex, size);
        return new SubList(this, offset, fromIndex, toIndex);
    }
    private void rangeCheck(int index) {//校验索引传入是否正确
        if (index < 0 || index >= this.size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
    private void rangeCheckForAdd(int index) {
        if (index < 0 || index > this.size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
    private String outOfBoundsMsg(int index) {
        return "Index: "+index+", Size: "+this.size;
    }
    private void checkForComodification() {
        if (ArrayList.this.modCount != this.modCount)
              throw new ConcurrentModificationException();
    }
    public Spliterator<E> spliterator() {
        checkForComodification();
        return new ArrayListSpliterator<E>(ArrayList.this, offset, offset + this.size, this.modCount);
    }
}

Java8新增lambda表达式操作

相较于Java7版本,Java8增加了一个特色操作lambda表达式,在代码实现上更加简化。其中接口Consumer和接口Predicate等都是从Java8引入的。

@Override
public void forEach(Consumer<? super E> action) {//遍历链表每一个元素执行action中定义的操作
    Objects.requireNonNull(action);
    final int expectedModCount = modCount;
    @SuppressWarnings("unchecked")
    final E[] elementData = (E[]) this.elementData;
    final int size = this.size;
    for (int i=0; modCount == expectedModCount && i < size; i++) {
        action.accept(elementData[i]);//对链表中每个元素执行action中定义的操作
    }
    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }
}
@Override
public boolean removeIf(Predicate<? super E> filter) {//如果元素满足过滤条件filter则删除
    Objects.requireNonNull(filter);
    // figure out which elements are to be removed
    // any exception thrown from the filter predicate at this stage
    // will leave the collection unmodified
    int removeCount = 0;
    final BitSet removeSet = new BitSet(size);//BitSet为位集合
    final int expectedModCount = modCount;
    final int size = this.size;
    for (int i=0; modCount == expectedModCount && i < size; i++) {
        @SuppressWarnings("unchecked")
        final E element = (E) elementData[i];
        if (filter.test(element)) {//filter的test函数测试通过,放入要删除的removeSet中
            removeSet.set(i);//相应位置设置为true
            removeCount++;
        }
     }
     if (modCount != expectedModCount) {
         throw new ConcurrentModificationException();
     }
    // shift surviving elements left over the spaces left by removed elements
    final boolean anyToRemove = removeCount > 0;
    if (anyToRemove) {
        final int newSize = size - removeCount;
        for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
            i = removeSet.nextClearBit(i);//从当前i位置起(包括i)找到第一个设置为false的值,证明不在removeSet中,需要保留
            elementData[j] = elementData[i];//复制保留
         }
        for (int k=newSize; k < size; k++) {//其余不需要的元素删除
            elementData[k] = null;  // Let gc do its work
        }
        this.size = newSize;
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
        modCount++;
    }
    return anyToRemove;
}
@Override
@SuppressWarnings("unchecked")
public void replaceAll(UnaryOperator<E> operator) {//传入一元操作
    Objects.requireNonNull(operator);
    final int expectedModCount = modCount;
    final int size = this.size;
    for (int i=0; modCount == expectedModCount && i < size; i++) {
        elementData[i] = operator.apply((E) elementData[i]);//对链表每个元素执行一元操作,然后代替原来的元素
    }
    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }
    modCount++;
}

元素的排序

@Override
@SuppressWarnings("unchecked")
public void sort(Comparator<? super E> c) {
    final int expectedModCount = modCount;
    //使用给定比较类c中定义的比较方法对数组进行排序
    //Arrays.sort默认使用归并排序和二叉排序
    Arrays.sort((E[]) elementData, 0, size, c);
    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }
    modCount++;
}

支持并发迭代的ArrayListSpliterator迭代器

@Override
public Spliterator<E> spliterator() {//创建ArrayListSpliterator迭代器
    return new ArrayListSpliterator<>(this, 0, -1, 0);
}
static final class ArrayListSpliterator<E> implements Spliterator<E> {
    private final ArrayList<E> list;
    private int index; // current index, modified on advance/split 起始位置
    private int fence; // -1 until used; then one past last index  结束位置
    private int expectedModCount; // initialized when fence set
    /** Create new spliterator covering the given  range */
    ArrayListSpliterator(ArrayList<E> list, int origin, int fence, int expectedModCount) {
        this.list = list; // OK if null unless traversed
        this.index = origin;
        this.fence = fence;
        this.expectedModCount = expectedModCount;
    }
    private int getFence() { // initialize fence to size on first use 返回当前ArrayListSpliterator的结束位置
        int hi; // (a specialized variant appears in method forEach)
        ArrayList<E> lst;
        if ((hi = fence) < 0) {//如果fense为-1需要设置为链表的size
            if ((lst = list) == null)
                hi = fence = 0;
            else {
                expectedModCount = lst.modCount;
                hi = fence = lst.size;
            }
         }
         return hi;
    }
    public ArrayListSpliterator<E> trySplit() {
    //尝试将链表拆分成小的链表视图,每次返回之前拆分余下链表元素的前一半
        int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
        return (lo >= mid) ? null : // divide range in half unless too small
            new ArrayListSpliterator<E>(list, lo, index = mid, expectedModCount);
    }
    public boolean tryAdvance(Consumer<? super E> action) {
        //试着去访问拆分为遍历到的元素,如果有未遍历到的元素执行action操作,并且返回true
        //如果没有为遍历到的元素,不执行操作,直接返回false
        if (action == null)
            throw new NullPointerException();
        int hi = getFence(), i = index;
        if (i < hi) {
            index = i + 1;
            @SuppressWarnings("unchecked") E e = (E)list.elementData[i];
            action.accept(e);
            if (list.modCount != expectedModCount)
                throw new ConcurrentModificationException();
            return true;
        }
        return false;
    }
    public void forEachRemaining(Consumer<? super E> action) {
        //遍历拆分队列区间内的每一个元素,执行action操作
        int i, hi, mc; // hoist accesses and checks from loop
        ArrayList<E> lst; Object[] a;
        if (action == null)
            throw new NullPointerException();
        if ((lst = list) != null && (a = lst.elementData) != null) {
            if ((hi = fence) < 0) {
                mc = lst.modCount;
                hi = lst.size;
            }
            else
                mc = expectedModCount;
            if ((i = index) >= 0 && (index = hi) <= a.length) {
                for (; i < hi; ++i) {
                    @SuppressWarnings("unchecked") E e = (E) a[i];
                    action.accept(e);
                }
                if (lst.modCount == mc)
                    return;
             }
         }
         throw new ConcurrentModificationException();
     }
     public long estimateSize() {//估算拆分队列的大小
         return (long) (getFence() - index);
     }
     public int characteristics() {//返回Spliterator的特征值
         return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
     }
}

余下的一个变量用于序列化使用

private static final long serialVersionUID = 8683452581122892189L;

总结

我们逐一介绍Java8中ArrayList的全部实现细节,几乎每一条语句都添加详细的讲解,阅读源码有助于提升自己的编程能力,就好比读一本好书可以渐渐培养自己的写作能力一样。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,924评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,902评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,716评论 0 239
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,783评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,166评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,510评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,784评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,476评论 0 196
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,196评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,459评论 2 243
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,978评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,321评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,964评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,046评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,803评论 0 193
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,530评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,420评论 2 265

推荐阅读更多精彩内容