集合容器-ArrayList

ArrayList流程图

ArrayList源码

step1:new ArrayList();
初始化ArrayList实例,elementData={}

/**
 * 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 = {};
/**
 * Constructs an empty list with an initial capacity of ten.
 */
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

step2:list.add(”a1“);
新增元素

/**
 *The size of the ArrayList (the number of elements it contains).
 *ArrayList中包含的元素数量
 */
private int size;

/**
 * Default initial capacity.
 * 默认容量
 */
private static final int DEFAULT_CAPACITY = 10;

/**
 * 记录着集合的修改次数,就是每次add或者remove后,modCount的值会加1
 * ArrayList是非线程安全的,在使用迭代器遍历的时候,用来检查列表中的元素是否发生结构性变化时需要使用,防止一个线程正在迭代遍历,另一个线程修改了这个列表的结构
 */
protected transient int modCount = 0;

/**
 * Appends the specified element to the end of this list.
 * 新增元素操作
 */
public boolean add(E e) {
	//确定是否需要扩容,如果需要则进行扩容操作
	//第一次添加操作时,size=0
    ensureCapacityInternal(size + 1); 
    //对下标为size的数组位置赋值,同时将下标移动到下一个
    elementData[size++] = e;
    return true;
}
//设置容量,第一次新增元素时minCapacity=1
private void ensureCapacityInternal(int minCapacity) {
	//第一次新增元素,calculateCapacity方法返回值为DEFAULT_CAPACITY,10
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
/**
 * 如果elementData数组中没有已存储的元素,则返回默认值10
 * 否则,返回miniCapacity
 * @param elementData 底层存储ArrayList元素的数组
 * @param minCapacity ArrayList中的元素个数
 */
//第一次新增元素时,elementData={},minCapacity=1
private static int calculateCapacity(Object[] elementData, int minCapacity) {
   if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
   		//DEFAULT_CAPACITY=10
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}
/**
 * 确保明确的ArrayList的容量
 * @param minCapacity ArrayList所需的最小容量
 * 
 * 第一次新增元素,minCapacity=10
 */
private void ensureExplicitCapacity(int minCapacity) {
	//修改次数,从0开始
    modCount++;
    // overflow-conscious code
    //如果所需的最小容量大于elementData数组的容量,则进行扩容操作
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

/**
 * 扩容操作
 * @param minCapacity 所需要的最小扩容量
 * 
 * 第一次新增元素,minCapacity=10,即:需要将elementData为0的长度扩容为10长度
 */
private void grow(int minCapacity) {
    // 原有数组elementData的程度
    int oldCapacity = elementData.length;
	 //A>>1 等于 A/2
	 //A<<1 等于 A*2
	 //新增oldCapacity的一半整数长度作为newCapacity
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    //新的长度newCapacity依然无法满足需要的最小扩容量minCapacity,则新的扩容长度为minCapacity
    if (newCapacity - minCapacity < 0){
    	newCapacity = minCapacity;
    }
    //校验新的扩容长度newCapacity是否超过最大限制,MAX_ARRAY_SIZE=Integer.MAX_VALUE - 8;
    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);
}

step3:list.set(0,obj);
修改元素

/**
 * Replaces the element at the specified position in this list with
 * the specified element.
 *
 * @param index index of the element to replace 需要替换的元素下标
 * @param element element to be stored at the specified position 新的值
 * @return the element previously at the specified position 被替换的值
 */
public E set(int index, E element) {
	//校验下标是否越界
    rangeCheck(index);
    //获取下标为index的元素的旧值
    E oldValue = elementData(index);
    //将新值设置的下标index位置
    elementData[index] = element;
    return oldValue;
}

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

setp4:list.get(index)
读取元素

/**
 * Returns the element at the specified position in this list.
 *
 */
public E get(int index) {
	//校验下标index是否越界
    rangeCheck(index);
	//返回下标index的值
    return elementData(index);
}

setp5:list.remove(index)
删除元素

/**
 * Removes the element at the specified position in this list.
 * Shifts any subsequent elements to the left (subtracts one from their
 * indices).
 *
 * 删除元素
 */
public E remove(int index) {
	//校验下标index是否越界
    rangeCheck(index);
	//记录异常修改
    modCount++;
    //获取下标index的值
    E oldValue = elementData(index);
	//需要移动的长度
    int numMoved = size - index - 1;
    if (numMoved > 0)
    	//从需要删除的index后一位开始到末尾的这部分数据,整体都向前移动一个元素
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    //通知jvm将之前的最后一位元素进行垃圾回收,同时将数组长度size减1
    elementData[--size] = null; // clear to let GC do its work

    return oldValue;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值