小言_互联网的博客

ArrayList部分源码分析-添加元素流程

409人阅读  评论(0)

属性

	// 序列化版本号
	private static final long serialVersionUID = 8683452581122892189L;
	// 默认数组初始化大小
 	private static final int DEFAULT_CAPACITY = 10;
 	// 默认空数组(初始化用)
 	private static final Object[] EMPTY_ELEMENTDATA = {};
 	// 默认空数组(判断是否为初始化对象用)
 	private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
 	// transient 代表此对象不可被序列化,因为此对象可能存在大量未使用空间,序列化可能会造成浪费
 	transient Object[] elementData; 
 	// 数组内实际元素数量
 	private int size;

方法

ArrayList(int initialCapacity)

	public ArrayList(int initialCapacity) {
		/*	初始化对象数组大小:
			1.若传入参数 > 0 ,则用参数作为数组大小;
			2.若传入参数 = 0 ,则用默认空数组;
			3.若传入参数 < 0 ,则抛出错误
		*/
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);
        }
    }

ArrayList()

	public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

add(E e)

	public boolean add(E e) {
		// 调用ensureCapacityInternal计算和确认容积
        ensureCapacityInternal(size + 1);  
        // 将新元素加入数组
        elementData[size++] = e;
        return true;
    }

ensureCapacityInternal(int minCapacity)

	private void ensureCapacityInternal(int minCapacity) {
		// calculateCapacity计算容积,ensureExplicitCapacity确认容积
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

calculateCapacity(Object[] elementData, int minCapacity)

	private static int calculateCapacity(Object[] elementData, int minCapacity) {
        // 如果数组地址等于默认空数组地址,则初始化数组容积
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        	// 将实际需求容积和默认数组容积中较大的那个作为数组容积
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }

ensureExplicitCapacity(int minCapacity)

	private void ensureExplicitCapacity(int minCapacity) {
		// 修改次数+1,fail-fast机制
        modCount++;
        // 判断计算的容积是否大于当前容积
        if (minCapacity - elementData.length > 0)
        	// 对数组扩容
            grow(minCapacity);
    }

grow(int minCapacity)

	private void grow(int minCapacity) {
        int oldCapacity = elementData.length;
        // 新数组容积为旧数组容积的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        // 如果新数组容积小于计算后的容积,那就使用计算后的容积
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        // 如果新数组的大小大于JVM可定义最大数组长度,创建一个合理数组或报错
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // 将旧数组的内容和新数组的大小一同复制给旧对象数组,进行扩容(此处注意引用的改变)
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

执行流程

思路:调用构造方法,创建数组对象 -》 
     将元素添加到数组中 -》 
     add内部先计算容积 -》
     根据计算后的容积和当前容积选择是否扩容 -》
     若扩容,则判断默认扩容机制和实际需要的容量进行对比;如不扩容,则将元素直接添加到数组末尾

ps

请把你们的意见和建议写在评论区里,谢谢~(@^_^@)~

转载:https://blog.csdn.net/qq_42462847/article/details/104912464
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场