关于ArraryList的源码简单分析

public class ArrayList extends AbstractList
        implements List, RandomAccess, Cloneable, java.io.Serializable
{
    private static final long serialVersionUID = 8683452581122892189L;

    /**
     * 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 static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    /**
     * 空元素数组
     */
    transient Object[] elementData; // non-private to simplify nested class access

    /**
     * The size of the ArrayList (the number of elements it contains).容量大小的计量器
     *
     * @serial
     */
    private int size;

    /**
     *初始化arrarylist 如果大于0 容量为输入的数,为0就是空的数组,小于0报错
     */
    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

    /**初始化arrarylist默认为DEFAULTCAPACITY_EMPTY_ELEMENTDATA
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    /**传入collection初始化arrarylist
     */
    public ArrayList(Collection c) {
    //将collection转为数组
        elementData = c.toArray();
        //将数组的长度赋值给size容量记录单位并判断是否等于0
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            //判断数组元素是否为Object类型不是则进行类型转换再进行复制
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

    /**当容器中有多余的未利用空间时调用此方法可去除空去空间
     */
    public void trimToSize() {
        modCount++;
        if (size < elementData.length) {
            elementData = (size == 0)
              ? EMPTY_ELEMENTDATA
              : Arrays.copyOf(elementData, size);
        }
    }

    /**
     * @param   minCapacity   the desired minimum capacity这个是arrarylist的扩容机制,
     */
    public void ensureCapacity(int minCapacity) {
    //首先判断elementData是不是默认的空容器是容量为0否则容量为默认的大小10
        int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
            // any size if not default element table
            ? 0
            // larger than default for default empty table. It's already
            // supposed to be at default size.
            : DEFAULT_CAPACITY;
            
        //对最开始处理的结果与传过来的参数对比如果最开始的小怎么调用方法
        if (minCapacity > minExpand) {
            ensureExplicitCapacity(minCapacity);
        }
    }

    private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }

    private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code 和数组的长度做比较如果参数大于原有数组长度怎掉grow();
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

    /**
     容器最大的容量
     */
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    /** grow()是list扩容的处理方法
     */
    private void grow(int minCapacity) {
        // overflow-conscious code获取容器中数组最开始的长度
        int oldCapacity = elementData.length;
        //对原先的数组长度向右移动一个2进制的数再加上原先的长度也就是原先的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        //判断新的扩容数组是否大与参数值决定新的数组长度
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        //判断新的扩容数组是否容器的最大容量
        if (newCapacity - MAX_ARRAY_SIZE > 0)
        //hugeCapacity()方法的处理逻辑是如果参数直接为负数则报错outofmemory,如果不是负数怎判断是否大于MAX_ARRAY_SIZE是则
        //容量为Iteger.MAXVALUE不知则复制为MAX_ARRAY_SIZE;
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        //执行copyOf方法创建新数组并赋值
        elementData = Arrays.copyOf(elementData, newCapacity);
    }


    //hugeCapacity()方法的处理逻辑是如果参数直接为负数则报错outofmemory,如果不是负数怎判断是否大于MAX_ARRAY_SIZE是则
    //容量为Iteger.MAXVALUE不知则复制为MAX_ARRAY_SIZE;
    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

    
    public int size() {
        return size;
    }

    /**
     *判断size是否为零
     */
    public boolean isEmpty() {
        return size == 0;
    }

    /**
     通过idexof()获取下标志 如果没有小标怎返回-1不大于零则不存在这个元素
     */
    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }

     //第一个o元素返回节点元素为o的下标
    public int indexOf(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

    //倒数第一个o元素返回节点元素为o的下标
    public int lastIndexOf(Object o) {
        if (o == null) {
            for (int i = size-1; i >= 0; i--)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = size-1; i >= 0; i--)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

   

   
     //转换为数组
    public Object[] toArray() {
        return Arrays.copyOf(elementData, size);
    }

    //转换为数组
    @SuppressWarnings("unchecked")
    public T[] toArray(T[] a) {
        if (a.length < size)
            // Make a new array of a's runtime type, but my contents:
            return (T[]) Arrays.copyOf(elementData, size, a.getClass());
        System.arraycopy(elementData, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }

    // Positional Access Operations

    @SuppressWarnings("unchecked")
    E elementData(int index) {
        return (E) elementData[index];
    }

    //获取index位置上的数据
    public E get(int index) {
        rangeCheck(index);

        return elementData(index);
    }

    //替换某一位置上的元素
    public E set(int index, E element) {
        //验证index的合理性
        rangeCheck(index);
        //获取这个位置上的原先数据
        E oldValue = elementData(index);
        //将这个节点数据重新赋值
        elementData[index] = element;
        //返回老数据
        return oldValue;
    }

    //添加元素
    public boolean add(E e) {
    //扩容
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        //将数组中第size++的节点赋值为额
        elementData[size++] = e;
        return true;
    }

   
     //向容器指定位置添加元素
    public void add(int index, E element) {
    //判断index是否合理不小于零且不大于容器的容量(size)
        rangeCheckForAdd(index);
        //扩容
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        //再原先数据放入新扩容的容器中
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        //将元素放入                 
        elementData[index] = element;
        //容量标记自加1
        size++;
    }

    
     //移除某一位置上的元素
    public E remove(int index) {
    //判断index是否合理
        rangeCheck(index);

        modCount++;
        //获取index位置上的数据
        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;
    }

   
     //根据数据移除返回boolean类型,先找到元素再执行fastRemove(index)操作"fastRemove(index)和remove(index)相比少了一个index合理性的判断"
    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])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }

    //见上一个方法
    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
    }

    
     //清空容器    对数组每个元素都赋值为null并将容量标记赋值为0;
    public void clear() {
        modCount++;

        // clear to let GC do its work
        for (int i = 0; i < size; i++)
            elementData[i] = null;

        size = 0;
    }

  
     //将collection添加到容器中
    public boolean addAll(Collection c) {
    //将collection转为数组
        Object[] a = c.toArray();
    //获取数组的长度
        int numNew = a.length;
        //扩容处理
        ensureCapacityInternal(size + numNew);  // Increments modCount
        //重置容器
        System.arraycopy(a, 0, elementData, size, numNew);
        //将数组长度和容器标记相加再赋值给容量标记
        size += numNew;
        return numNew != 0;
    }

   
     //在某个位置添加collection
    public boolean addAll(int index, Collection c) {
        //验证index的合理性
        rangeCheckForAdd(index);
        //处理c
        Object[] a = c.toArray();
        int numNew = a.length;
        //扩容处理
        ensureCapacityInternal(size + numNew);  // Increments modCount

        int numMoved = size - index;
        if (numMoved > 0)
            //数组扩容并将自身复制到新的数组中
            System.arraycopy(elementData, index, elementData, index + numNew,
                             numMoved);
        //将a复制到扩容之后的数组中
        System.arraycopy(a, 0, elementData, index, numNew);
        size += numNew;
        return numNew != 0;
    }

    
     //将某一处到某一端数据移除
    protected void removeRange(int fromIndex, int toIndex) {
        modCount++;
        int numMoved = size - toIndex;
        //直接进行容器重置
        System.arraycopy(elementData, toIndex, elementData, fromIndex,
                         numMoved);

        // clear to let GC do its work
        //将多余的数据清除
        int newSize = size - (toIndex-fromIndex);
        for (int i = newSize; i < size; i++) {
            elementData[i] = null;
        }
        size = newSize;
    }

    
     //验证数组下标是否越界
    private void rangeCheck(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    /**
     * 为添加验证数组下标是否合理
     */
    private void rangeCheckForAdd(int index) {
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    //数组下标越界错误字符串拼接
    private String outOfBoundsMsg(int index) {
        return "Index: "+index+", Size: "+size;
    }

    //只保留和c中元素不相同的元素
    public boolean removeAll(Collection c) {
        //验证对象c是否是null
        Objects.requireNonNull(c);
        return batchRemove(c, false);
    }

    //只保留和c中元素相同的元素
    public boolean retainAll(Collection c) {
        Objects.requireNonNull(c);
        return batchRemove(c, true);
    }


/*
  从容器中去除相同/不相同的集合的元素
*/
    private boolean batchRemove(Collection c, boolean complement) {
        final Object[] elementData = this.elementData;
        int r = 0, w = 0;
        boolean modified = false;
        try {
            for (; r < size; r++)
                //遍历自身容器将自身容器中与c中不同的元素取出
                if (c.contains(elementData[r]) == complement)
                    elementData[w++] = elementData[r];
        } finally {
            // Preserve behavioral compatibility with AbstractCollection,
            // even if c.contains() throws.
            if (r != size) {
                //将前w位用来存放不一样的元素
                System.arraycopy(elementData, r,
                                 elementData, w,
                                 size - r);
                w += size - r;
            }
            if (w != size) {
                //  将容器中的w位往后的所有一样的元素全部清除出去
                for (int i = w; i < size; i++)
                    elementData[i] = null;
                modCount += size - w;
                size = w;
                modified = true;
            }
        }
        return modified;
    }

 }
 

你可能感兴趣的:(JDK源码)