Java中ArrayList的实现原理

来源:互联网 发布:富二代的生活 知乎 编辑:程序博客网 时间:2024/06/09 16:23

ArrayList是一个实现List接口的可变数组,它可以存放所有种类的元素,包括null。

ArrayList底层是用数组实现的,只是在这基础上封装了一些方法,使其达到可变数组的效果。

下面就来介绍ArrayList的实现原理。

/**     * Constructs an empty list with the specified initial capacity.     *     * @param  initialCapacity  the initial capacity of the list     * @throws IllegalArgumentException if the specified initial capacity     *         is negative     */    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() {        super();        this.elementData = EMPTY_ELEMENTDATA;    }    /**     * Constructs a list containing the elements of the specified     * collection, in the order they are returned by the collection's     * iterator.     *     * @param c the collection whose elements are to be placed into this list     * @throws NullPointerException if the specified collection is null     */    public ArrayList(Collection<? extends E> c) {        elementData = c.toArray();        size = elementData.length;        // c.toArray might (incorrectly) not return Object[] (see 6260652)        if (elementData.getClass() != Object[].class)            elementData = Arrays.copyOf(elementData, size, Object[].class);    }
这是ArrayList的三个构造方法,第一个构造方法带有一个int类型参数,指定初始容量,第二个是无参构造,初始容量为10,第三个是带有一个Collection参数,将Collection中的所有参数复制到ArrayList。

再来看ArrayList.add(E e)方法

public boolean add(E e) {        ensureCapacityInternal(size + 1);  // Increments modCount!!        elementData[size++] = e;        return true;    }
这个add方法和向普通数组中插入元素类似,但是它前面有一个ensureCapacityInternal(int)方法,这就是ArrayList实现可变数组功能的关键。
 private void ensureCapacityInternal(int minCapacity) {        if (elementData == EMPTY_ELEMENTDATA) {            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);        }        ensureExplicitCapacity(minCapacity);    }    private void ensureExplicitCapacity(int minCapacity) {        modCount++;        // overflow-conscious code        if (minCapacity - elementData.length > 0)            grow(minCapacity);    }
在ensureCapacityInternal(int)方法中,首先确定最小容量,然后通过ensureExplicitCapacity(int )来判断存放元素的数组大小是否小于最小容量,如果数组大小小于最小容量,则需要扩大数组大小,这里就用到了grow(int )方法

private void grow(int minCapacity) {        // overflow-conscious code        int oldCapacity = elementData.length;        int newCapacity = oldCapacity + (oldCapacity >> 1);        if (newCapacity - minCapacity < 0)            newCapacity = minCapacity;        if (newCapacity - MAX_ARRAY_SIZE > 0)            newCapacity = hugeCapacity(minCapacity);        // minCapacity is usually close to size, so this is a win:        elementData = Arrays.copyOf(elementData, newCapacity);    }    private static int hugeCapacity(int minCapacity) {        if (minCapacity < 0) // overflow            throw new OutOfMemoryError();        return (minCapacity > MAX_ARRAY_SIZE) ?            Integer.MAX_VALUE :            MAX_ARRAY_SIZE;    }
这段代码中重点就是newCapacity = oldCapacity + (oldCapacity >> 1),新的容量为原来容量的1.5倍,并且将原来的数组元素复制到新的数组中。

关于ArrayList实现原理的介绍就到此结束啦微笑