Java源码阅读-ArrayList

来源:互联网 发布:网络推广活动方案 编辑:程序博客网 时间:2024/05/20 14:26
/**     * Default initial capacity.     */    private static final int DEFAULT_CAPACITY = 10; // 默认的容量,10    /**     * Shared empty array instance used for empty instances.     */    private static final Object[] EMPTY_ELEMENTDATA = {}; // 初始值,一个空的Object数组    /**     * The array buffer into which the elements of the ArrayList are stored.     * The capacity of the ArrayList is the length of this array buffer. Any     * empty ArrayList with elementData == EMPTY_ELEMENTDATA will be expanded to     * DEFAULT_CAPACITY when the first element is added.     */    private transient Object[] elementData; // 元素数组    /**     * The size of the ArrayList (the number of elements it contains).     *     * @serial     */    private int size; // 元素的实际个数


构造函数

/**     * 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]; // 使用传入的容量值创建一个object数组    }    /**     * Constructs an empty list with an initial capacity of ten.     */    public ArrayList() { // 构造函数之一,不传参数        super();        this.elementData = EMPTY_ELEMENTDATA;    }


添加元素
/**     * Appends the specified element to the end of this list.     *     * @param e element to be appended to this list     * @return <tt>true</tt> (as specified by {@link Collection#add})     */    public boolean add(E e) { // 插入元素        ensureCapacityInternal(size + 1);  // Increments modCount!! 扩容,如果需要的话        elementData[size++] = e;        return true;    }
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);    }
/**     * Increases the capacity to ensure that it can hold at least the     * number of elements specified by the minimum capacity argument.     *     * @param minCapacity the desired minimum capacity     */    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) // 新的容量比数组的最大长度还大,取数组的最大长度和Integer类的最大值的较大值            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;    }
/**     * The maximum size of array to allocate.     * Some VMs reserve some header words in an array.     * Attempts to allocate larger arrays may result in     * OutOfMemoryError: Requested array size exceeds VM limit     */    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; // 数组的最大长度


删除元素

/**     * Removes the element at the specified position in this list.     * Shifts any subsequent elements to the left (subtracts one from their     * indices).     *     * @param index the index of the element to be removed     * @return the element that was removed from the list     * @throws IndexOutOfBoundsException {@inheritDoc}     */    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; // clear to let GC do its work        return oldValue;    }
/**     * Checks if the given index is in range.  If not, throws an appropriate     * runtime exception.  This method does *not* check if the index is     * negative: It is always used immediately prior to an array access,     * which throws an ArrayIndexOutOfBoundsException if index is negative.     */    private void rangeCheck(int index) { // 检查数组下标是否越界        if (index >= size)            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));    }
/**     * Removes the first occurrence of the specified element from this list,     * if it is present.  If the list does not contain the element, it is     * unchanged.  More formally, removes the element with the lowest index     * <tt>i</tt> such that     * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>     * (if such an element exists).  Returns <tt>true</tt> if this list     * contained the specified element (or equivalently, if this list     * changed as a result of the call).     *     * @param o element to be removed from this list, if present     * @return <tt>true</tt> if this list contained the specified element     */    public boolean remove(Object o) { // 根据元素对象删除        if (o == null) {            for (int index = 0; index < size; index++)                if (elementData[index] == null) {                    fastRemove(index);                    return true;                }        } else {            for (int index = 0; index < size; index++)                if (o.equals(elementData[index])) { // 注意,如果是自定义的类型,需要注意重写equals,否则equals默认比较的是地址,传入的对象和list中的对象地址不同,不会删除                    fastRemove(index);                    return true;                }        }        return false;    }
/*     * Private remove method that skips bounds checking and does not     * return the value removed.     */    private void fastRemove(int index) {        modCount++;        int numMoved = size - index - 1;        if (numMoved > 0)            System.arraycopy(elementData, index+1, elementData, index,                             numMoved);        elementData[--size] = null; // clear to let GC do its work    }



原创粉丝点击