ArrayList源码简单剖析


    private static final int DEFAULT_CAPACITY = 10;

    private static final Object[] EMPTY_ELEMENTDATA = {};

    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

 
    transient Object[] elementData; // non-private to simplify nested class access

    private int size;


   public ArrayList(int initialCapacity) { // 1.ArrayList构造方法,可以指定默认的初始化大小,当然还有个无参构造,默认是个Object类型空数组
        // 2.下面的逻辑判断应该都能看的懂,比较简单
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }


    // get方法:传递个索引值过来,判断索引是否大于size;如果大于抛出个索引越界异常,否则返回数组对应索引的上的元素
     public E get(int index) {
        rangeCheck(index);

        return elementData(index);
    }

    private void rangeCheck(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }


    //set方法:通过索引获取到该位置上的元素,赋值给了oldValue这个变量;然后再把传递过来的元素赋值到该位置的索引上;通过set改变元素时,可以返回老的元素
    public E set(int index, E element) {
        rangeCheck(index);

        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }


    //add方法: 6.跟的方法有点深,不好意思;但总体来说就是add一个元素进去,在当前size+1;如果size长度不够就去填充;最后把这个元素指定到当前size的数组索引上返回布尔值TRUE
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // 1.当add一个元素进来的时候当前的size+1值走ensureCapacityInternal方法
        elementData[size++] = e;
        return true;
    }

    private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));// 2.elementData默认是一个空数组
    }

     private static int calculateCapacity(Object[] elementData, int minCapacity) { 
        // 3.判断是否是空数组
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            // 4.当添加一个元素进来的时候,ArrayList会默认扩容到10
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }

    // 5.下面这个几个方法简单可以理解成,一个扩容的过程就不多说了
    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; 

    private void grow(int minCapacity) {
        int oldCapacity = elementData.length;
        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);
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) 
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :   // Integer.MAX_VALUE  一个持有最大值一个 int可以有2的31次方-1。 
            MAX_ARRAY_SIZE;
    }

    // remove方法:
    public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);

        //size是这个集合的长度,获取传递过来的索引位置并且-1的个数,然后通过 System.arraycopy方法进行复制,把原数组覆盖.最后把这个size的最后一位至为null,并且size--的方式进行删除
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; 

        return oldValue;
    }

猜你喜欢

转载自blog.csdn.net/qq_40274514/article/details/82192987