ArrayList详细分析(一)构造函数和添加方法

AarrayList底层代码展示:(RandomAccess, Cloneable, java.io.Serializable三个标记性接口具体内容在我博客里面有详细介绍)
先看下面三个属性:(第一反应解析是干什么用的)
DEFAULT_CAPACITY:默认的初始化大小
DEFAULTCAPACITY_EMPTY_ELEMENTDATA :空数组,没有具体初始化大小
elementData:数据具体存放的地方

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, 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 default sized empty instances. We
     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
     * first element is added.
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    /**
     * 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 == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
     * will be expanded to DEFAULT_CAPACITY when the first element is added.
     */
    transient Object[] elementData;

ArrayList无参构造函数源码看起;
仅仅就是elementData这个成员变量初始化赋值了一个空数组

/**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

ArrayList有参构造函数源码(参数为集合)
参数为集合中包含值就把参数直接赋值给目标集合
若没有值则赋值一个空数据

/**
     * 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();
        // private int size; 当前size=0
        //如果传进来的是一个有值的集合
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            //再次进行判断,类型判断
            if (elementData.getClass() != Object[].class)
                 //数组的创建和拷贝
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            //如果传进来是一个没有包含值的集合
            //private static final Object[] EMPTY_ELEMENTDATA = {};
            //还是把elementData初始化为一个空集合
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

重点看:
add方法的原理
直接总结:add方法才是List初始化长度的地方,grow为扩容的具体方法 每次扩容1.5倍
当长度为:MAX_ARRAY_SIZE 会执行hugeCapacity扩容Integer.MAX_VALUE - 8 21亿
ensureCapacityInternal方法为判断是否进行扩容
再往下看

这边提到了modCount,来看看是干啥的

/**
     * The size of the ArrayList (the number of elements it contains).
     *
     * @serial
     */
    private int size;
/**
     * 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;
    } 
/**
 * Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;

private void ensureCapacityInternal(int minCapacity) {
          //判断是否为一个空数组
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
             //判断DEFAULT_CAPACITY的值是否大于minCapacity 10>1
             //给minCapacity赋值为10 (第一次扩容,从0到10)
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }

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

        // overflow-conscious code
        // 10 -1
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
//grow是具体扩容的实现 是实际扩大数组长度的地方(核心算法:原容量的1.5倍)
  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:
        //newCapacity 为最终扩容后的数组长度。
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

     //elementData这个数组进行实例地添加元素  每次新元素都添加到最后 然后size 进行自增+1 
     //实际的把数据放入数据里面了
     elementData[size++] = e;

在指定位置添加元素 add(index,E element)源码

/**
     * Inserts the specified element at the specified position in this
     * list. Shifts the element currently at that position (if any) and
     * any subsequent elements to the right (adds one to their indices).
     *
     * @param index index at which the specified element is to be inserted
     * @param element element to be inserted
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public void add(int index, E element) {
        //判断index是否越界了
        rangeCheckForAdd(index);
        //判断是否需要扩容
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        //数组的拷贝
        //[1,2,3,4]
        //若index=1 elementData, index,size - index:表示的范围是 2.3,4
        //最后结果为:[1,0,2,3,4]
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }
    
   /**
     * A version of rangeCheck used by add and addAll.
     */
    private void rangeCheckForAdd(int index) {
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

.addAll(List) 向集合中添加集合源码

 public boolean addAll(int index, Collection<? extends E> c) {
            //当前index为原集合的size长度
            rangeCheckForAdd(index);
            int cSize = c.size();
            //如果要添加的集合元素
            if (cSize==0)
                return false;

            checkForComodification();
            parent.addAll(parentOffset + index, c);
            this.modCount = parent.modCount;
            this.size += cSize;
            return true;
        }
        //判断扩容的次数
        private void checkForComodification() {
            if (ArrayList.this.modCount != this.modCount)
                throw new ConcurrentModificationException();
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值