ArrayList源码解析

UML

ArrayList UML

主要代码

ArrayList实现了List、RandomAccess、Cloneable、Serializable,继承了AbstractList。
为什么继承了AbstractList还要实现List接口?
AbstractList中已经实现了List接口,这里其实是没有必要再实现List接口的,这个获取是为了体现面向接口编程。
RandomAccess接口:该接口在jdk中是一个空实现,是一个标记接口。文档指明实现了RandomAccess说明List支持随机访问。这个接口的主要目的是允许普通算法对随机方法或者连续访问List时,改变其行为,以获得较好的性能。

默认初始容量为10,每次扩容1.5倍,底部存储使用数组。

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
    // 默认容量10
    private static final int DAFAULT_CAPACITY = 10;
    // 当传入的容量大小为0时,使用该空的常量数组对象来初始化底层数组elementData
    private static final Object[] EMPTY_ELEMENTDATA = {};
    
    // 当未指定容量大小时,使用该空的常量数组对象来初始化底层数组elementData,,这时,当第一次添加元素时,将会默认创建一个容量为10的默认容量数组。
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    
    // 存储ArrayList中的元素,使用transient是为了不序列化这个字段
    transiemt Object[] elementData;
    
    // 集合中元素的个数, 不是底层数组elementData的长度
    private int size; 
    
    // 最大容量,即elementData数组的最大长度,超过该长度将会抛出OutOfMemoryError
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    
    // 结构性修改次数,定义在AbstractList中
    protected transient int modCount = 0;
    
    /**
     * 构造一个指定容量的集合
     * 根据参数大小做为容量来实例化底层的数组对象,当参数等于0时,用空的常量数组对象EMPTY_ * ELEMENTDATA来初始化底层数组elementData
     */
    public ArrayList(int initialCapacity) {
        if(initialCapacity > 0) {
            this.elementData = new Object[intialCapacity];
        }else if(initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        }else {
            throw new IllegalArgumentException("Illegal Capacityy : " + initialCapacity);;
        }
    } 
    
    /**
     * 构造一个初始容量为10的空集合
     * 这里并没有指定容量,那么我们怎么知道是10呢?答案请看add(E e)
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENT;
    }
    
    /**
     * 将容器Collection转化为数组赋值给底层数组elementData
     */
    public ArrayList(Collection<? extends E> c) {
        // 集合转化为数组
        elelementData = c.toArray();
        if((size = elementData.length) != 0) {
            // 将c.toArray()返回的是不是Object[]类型,如果不是重新拷贝生成Object[]类型
            if(elementData.getClass != Object[].class) {
                elementData = Arrays.copyOf(lementData, size, Ojbect[].class);
            }
        }else {
            // 如果是空集合,则初始化为空数组EMPTY_ELEMENTDATA
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }
    
    /**
     * 将指定元素e添加到list的末尾,平均时间时间复杂度O(1)
     * 1.计算最小容量minCapacity
     *   如果elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA,最小容量为max(DEFAULT_CAPACITY, minCapacity)
     *   否则为size + 1
     * 2.检查当前elementData容量是否够minCapacity,不够进行扩容
     * 3.将size位置的元素设置e
     */
    public boolean add(E e) {
        // 检查是否需要进行扩容
        ensureCapacityInternal(size + 1);
        // 将size位置设置为e,并将size++;
        elementData[size++] = e;
        return true;
    }
    
    /**
     * 添加元素到指定位置
     * 1.检查是否越界 0 <= index <= size
     * 2.检查是否需要扩容
     * 3.将index之后的元素后移一位
     * 4.设置index位置的元素为elementData
     */ 
    public void add(int index, E element) {
        rangeCheckForAdd(index);
        ensureCapacityInternal(size + 1);
        System.arraycopy(elementData, index, elementData, index + 1, size - index);
        elementData[index] = element;
        size++;
    }
    
    // addAll(Collection<? extends E> c)、addAll(int index, Collection<? extends E> c) 逻辑与add(int index, E element)相似
    
    public boolean addAll(Collection<? extends E> c) {
        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityInternal(size + numNew);
        
        System.arraycopy(a, 0, elementData, size, numNew);
        size += numNew;
        return numNew != 0;
    }
    
    public boolean addAll(int index, Collection<? extends E> c) {
        rangeCheckForAdd(index);
        Object[] a = c.toArray();
        int numNew = a.length;
        ensuerCapacityInternal(size + numNew);
        
        int numMoved = size - index;
        if(numMoved > 0) {
           System.arraycopy(elementData, index, elementData, index + numMoved , numMoved);
        }
        System.arraycopy(a, 0, elementData, index, numNew);
        size += numNew;
        return numNew != 0;
        
    }
    
    /**
     * 设置index位置的元素为element
     */
    public E set(int index, E element) {
        rangeCheck(index);
        
        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }
    
    /**
     * 获取指定位置index上的元素
     */
    public E get(int index) {
        // 检查是否越界 0 <= index < this.size
        rangeCheck(index);
        // 返回底层数组index位置的元素
        return elementData[index];
    }
    
    /**
     * 从头开始查找对象o在list中的索引位置
     * 查找分o为null和非null两种情况,没有找到返回-1
     */
    public int indexOf(Object o) {
        if(o == null) {
            for(int i = 0; i < size; i++) {
                if(elementData[i] == null) {
                    return i;
                }
            }
        }else {
            for(int i = 0; i < size; i ++) {
                if(o.equals(elementData[i])) {
                    return i;
                }
            }
        }
        return -1;
    }

    /**
     * 从尾部开始查找对象o所在索引位置
     */
    public int lastIndexOf(Object 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;
    }
    
    /**
     * 移除index位置的元素
     * 1.检查index是否越界
     * 2.结构性修改次数加1
     * 3.将index后面的元素向前移动一位
     * 4.将最后一位置为空,并返回移除的元素
     */
    public E remove(int index) {
        rangeCheck(index);
        
        modCount++;
        E oldValue = elementData[index];
        
        int numMoved = size - index - 1;
        if(numMoved > 0) {
            System.arraycopy(elementData, index + 1, elementData, index, numMoved);
        }
        elementData[--size] = null;
        return oldValue;
    }
    
    public boolean remove(Object o) {
        if(o == null) {
            for(int index = 0; index < size; index++) {
                if(elementData == null) {
                    fastRemove(index);
                    return true;
                }
            }
        } else {
            for(int index = 0; index < size; index++) {
                if(o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
            }
        }
        
        return false;
    }
    
    /**
     * 移除指定集合c中元素
     */ 
    public boolean removeAll(Collection<?> c) {
        // c不能为null
        Objects.requireNonNull(c);
        return batchRemove(c, false);
    }
    
    /**
     * 对list中的所有元素执行operator.apply()
     */
    public void replaceAll(UnaryOperator<E> oprator) {
        Objects.requireNonNull(operator);
        final int expectedModCount = modCount;
        final int size = this.size;
        for(int i = 0; modCount == expectedCount && i < size; i++) {
            elementData[i] = operator.apply((E)element[i]);
        }
        if(modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
        modCount++;
    }
    
    /**
     * list排序,直接调用Arrays.sort()。只对0,size之间的元素进行排序
     */
    public void sort(Comparator<? super E> c) {
        final int expectedModCount = modCount;
        Array.sort((E[]) elementData, 0, size, c);
        if(modCount != expectedModCount) {
            throw new ConcurrentModification Exception();
        }
        modCount++;
    }
    
    /**
     * elementData使用了transient,所以序列化时不会将elementData序列化,
     * 这里将ArrayList写入到序列化流中
     */
    private void writeObject(ObjectOutputStream s) throws IOException {
        int expectedModCount = modCount;
        s.defaultWriteObject();
        
        s.writeInt(size);
        for(int i = 0; i < size; i++) {
            s.writeObject(elementData[i]);
        }
        if(modCount != elementModCount) {
            throw new ConcurrentModificationException();
        }
    }
    
    /**
     * 从流中反序列化
     */
    private void readObject(ObjectInputStream s) throws IOEception, ClassNotFoundException {
        elementData = EMPTY_ELEMENTDATA;
        s.defaultReadObject();
        s.readInt();
        if(size > 0) {
            int capacity = calculateCapacity(elementData, size);
            Shared.getJavaOISAccess().checkArray(s, Object[].class, capacity);
            ensureCapacityInternal(size);
            
            Object[] a = elementData;
            for(int i = 0; i < size; i++) {
                a[i] = s.readObject();
                
            }
            
        }
    }
    
    
    private void fastRemove(index) {
        modCount++;
        int numMoved = size - index - 1;
        if(numMoved > 0) {
            System.arraycopy(elementData, index + 1, elementData, index, numMoved);
        }
        elementData[--size] = null;
    }
    
    private boolean batchRemove(Collection<?> c, boolean complement) {
        final Object[] elementData = this.elementData;
        int r = 0; w = 0;
        boolean modified = false;
        try {
            for(; r < size; r++) {
                if(c.contains(elementData[r]) == complement) {
                    // 如果list中该元素不存在与collection中,就放入elementData
                    elementData[w++] = elementData[r];
                }
            }finally {
                if(r != size) {
                    System.arraycopy(elementData, r, elementData, w, size - r);
                    w += size - r;
                }
                // 如果list中确实有collection中的元素,那么w一定不等于size
                if(w != size) {
                    // 将其他元素设置为null,这样elementData中就只有不在collection中的元素了,并且多余的索引位置并设置为了null
                    for(int i = w; i < size; i++) {
                        elementData[i] = null;
                    }
                    // 修改次数
                    modCount += size -w;
                    // size等于w
                    size = w;
                    // 移除过元素
                    modified = true;
                }
            }
            return modified;
        }
    }

    
    private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }
    
    /**
     * 计算最小容量
     * 1,如果elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA,那么取DEFAULT_CAPACITY和minCapacity中的较大者
     * 2.取minCapacity
     */
    private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPCITY, minCapacity);
        }
        return capacity;
    }
    
    /**
     * 如果所需的最小容量大于底层数组elementData的容量大小,进行扩容,否则直接返回
     */
    private void ensureExplicitCapacity(int minCapacity) {
        // 结构性修改次数—+1
        modCount++;
        // 如果所需的最小容量大于elementData的容量,进行扩容
        if(minCapacity - elementData.length > 0) {
            // 进行扩容
            grow(minCapacity);
        }
    }
    
    /**
     * 扩容
     */
    private void grow(int minCapacity) {
        // 当前数组容量
        int oldCapacity = elementData.length;
        // 新数组容量为旧数组容量的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        
        if(newCapacity - minCapacity < 0) {
           // 如果新数组容量还是不够(也有可能是溢出了),赋值新数组容量为所需的最小数组容量
            newCapacity = minCapacity;
        }
        
        if(newCapacity - MAX_ARRAY_SIZE > 0) {
            // 如果新数组容量比MAX_ARRAY_SIZE大,并且所需的minCapacity也大于MAX_ARRAY_SIZE,设置新容量为Integer.MAX_VALUE,否则设置为MAX_ARRAY_SIZE
            newCapacity = hugeCapacity(minCapacity);
        }
        // 将旧数组拷贝到新数组
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
    
    private static int hugeCapacity(int minCapacity) {
        if(minCapacity < 0) {
            throw new OutOfMemoryError();
        }
        return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
    }
    
    
    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));
        }
    }

    
    
    
}
原文地址:https://www.cnblogs.com/QullLee/p/11182299.html