jdk源码阅读笔记之java集合框架(二)(ArrayList)

关于ArrayList的分析,会从且仅从其添加(add)与删除(remove)方法入手。

ArrayList类定义:

public class ArrayList<E> extends AbstractList<E> implements List<E>

ArrayList基本属性:

 /**
     * Default initial capacity.(默认初始化大小)
     */
    private static final int DEFAULT_CAPACITY = 10;
    /**
     * Shared empty array instance used for empty instances.
     * 空数组,当调用无参数构造函数的时候默认给个空数组
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};
 
    /**
     * 真正存储数据的数组
     */
    private transient Object[] elementData;
 
    /**
     * The size of the ArrayList (the number of elements it contains).
     * 所存储数据的数量
     */
View Code

 ArrayList的add方法:

/**
     * Appends the specified element to the end of this list.
     * 插入数据,每一次都是从末尾插入
     */
    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++;//jdk源码阅读笔记之java集合框架(三)(modCount)
       if (minCapacity - elementData.length > 0)
            /**
        * minCapacity=size+1
        * 只用当数组实际存储元素数量+1大于数组长度是,需扩容
        */
        grow(minCapacity);
    }
    /**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     * 提高数组容量以确保至少能够存储minimum数量的数据
     */
    private void grow(int minCapacity) {
        int oldCapacity = elementData.length;
     
     //带符号右移等价于除以2,所以每一次扩容之后,数组的长度为原来的1.5倍。
        int newCapacity = oldCapacity + (oldCapacity >> 1);
 
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        //由于扩容之后产生了新数组,此处是新老数组之间数据的转移
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

ArrayList的remove方法:

remove方法分为 remove(Object o) 与 remove(int index)。俩方法类似,所以任挑其一进行分析。

 /**
     * 移除指定下标的元素
     */
    public E remove(int index) {
        rangeCheck(index);//下标越界检查

        modCount++; //"http://www.cnblogs.com/jw93/p/6845825.html"详细介绍
        E oldValue = elementData(index);

        /**
         * 移除某一元素之后,需要将该元素后面的元素向前移动
         * numMoved表示需要移动的元素个数
         */
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);//此处为native方法
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }
    /**
     * 下标越界检查
     */
    private void rangeCheck(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));//抛出数组下标越界
    }
    /**
     * 抛出异常时详细信息
     */
    private String outOfBoundsMsg(int index) {
        return "Index: "+index+", Size: "+size;
    }

 

 

 

 

 

 

posted @ 2017-05-12 17:13  蒋旺93  阅读(217)  评论(0编辑  收藏  举报