ArrayList源码分析

来源:互联网 发布:免费淘宝客软件 编辑:程序博客网 时间:2024/06/07 10:25

ArrayList 的底层通过数组进行存储;LinkedList的底层通过链表进行存储。

1.随机访问(通过Index访问数组元素),ArrayList效率较高;但删除元素效率不如LinkedList(需要对元素进行移动)

2.LinkedList新增、删除元素效率较高。


ArrayList的源码进行分析:

public class ArrayList<E> extends AbstractList<E>        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
==》通过类声明可以看出,ArrayList是List的子类,支持随机访问、深拷贝(clone)、序列化


1.核心属性:

A. elementData []: 数组,用来最终保存数据

    private transient Object[] elementData;

B. initialCapacity : 初始数组长度,默认为10

public ArrayList(int initialCapacity) {        super();        if (initialCapacity < 0)            throw new IllegalArgumentException("Illegal Capacity: "+                                               initialCapacity);        this.elementData = new Object[initialCapacity];    }    /**     * Constructs an empty list with an initial capacity of ten.     */    public ArrayList() {        this(10);}

C. size: 记录数组中元素的个数,默认为空,即size=0

    private int size;

2.核心操作(add()):

A.添加元素:

public boolean add(E e) {        ensureCapacityInternal(size + 1);  // Increments modCount!!        elementData[size++] = e;        return true;}
==》ensureCapasityInternal() : 首先判断数组是否已满,如果已满,对数组进行扩容

==》将元素添加到数组中

private void ensureCapacityInternal(int minCapacity) {        modCount++;        // overflow-conscious code        if (minCapacity - elementData.length > 0)            grow(minCapacity);}
==》扩容原理:创建新的数组==》将原始数组的值拷贝到新的数组中

public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {        T[] copy = ((Object)newType == (Object)Object[].class)            ? (T[]) new Object[newLength]            : (T[]) Array.newInstance(newType.getComponentType(), newLength);        System.arraycopy(original, 0, copy, 0,                         Math.min(original.length, newLength));        return copy;}


B.删除元素(delete())

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; // Let gc do its work        return oldValue;}
==> 首先验证index是否越界 : rangeCheck(index) 

==> 通过数组拷贝实现数据的移动(将index之后的元素向前移动,将index所在的元素覆盖)

==> 元素个数-1 : --size ; 并将原数组最后一个元素赋null(利于垃圾处理器回收 : 引用计数)


C.访问元素

public E get(int index) {        rangeCheck(index);        return elementData(index);}








原创粉丝点击