ArrayList源码分析

JDK17 ArrayList源码分析

//容器默认的初始化容量
private static final int DEFAULT_CAPACITY = 10;

//用于空实例的共享空数组实例
private static final Object[] EMPTY_ELEMENTDATA = {};

//共享空数组实例,用于默认大小的空实例。我们将其与EMPTY_ELEMENTDATA区分开来,以便知道在添加第一个元素时膨胀多少。
 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
 
//数组缓冲区,存储数组列表中的元素。数组列表的容量是这个数组缓冲区的长度。当第一个元素被添加时,任何带有elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA的空ArrayList将被扩展为DEFAULT_CAPACITY。
transient Object[] elementData;

//数组列表的大小(它当前包含的元素的数量)。
private int size;

在这里插入图片描述

默认的三个构造函数

	/**
	*	按照给定的大小初始化elementData
	*/
	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);
        }
    }

    /**
     * 无参的构造方法,在第一次使用add方法时,会将elementData膨胀为大小为10的数组
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    /**
	 * 按照指定的集合初始化elementdata
     */
    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        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.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

add方法

	public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // 用来确保当前数组不会越界,在满足条件时进行膨胀
        elementData[size++] = e;
        return true;
    }

ensureCapacityInternal方法

private void ensureCapacityInternal(int minCapacity) {
    //calculateCapacity:如果是调用无参的构造方法来构造的对象,首次添加时则默认返回了DEFAULT_CAPACITY:大小为10,否则就返回在原size+1的值
    //ensureExplicitCapacity:用来确保当前存储数组elementData长度是否已经到达最大,并在一定条件下进行扩容
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}

calculateCapacity,首次添加的时候,增加为默认大小10

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

ensureExplicitCapacity方法:用来确保当前存储数组elementData长度是否已经到达最大,并在一定条件下进行扩容

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

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
        // 如果已经到达最大,则进行扩容
            grow(minCapacity);
    }

关键方法grow()

private Object[] grow(int minCapacity) {
        int oldCapacity = elementData.length;
        if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            int newCapacity = ArraysSupport.newLength(oldCapacity,
                    minCapacity - oldCapacity, /* minimum growth */
                    oldCapacity >> 1           /* preferred growth */);
            return elementData = Arrays.copyOf(elementData, newCapacity);
        } else {
            return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
        }
    }

ArraysSupport的newlength方法

	public static final int SOFT_MAX_ARRAY_LENGTH = Integer.MAX_VALUE - 8;

	public static int newLength(int oldLength, int minGrowth, int prefGrowth) {
        // preconditions not checked because of inlining
        // assert oldLength >= 0
        // assert minGrowth > 0
        
		// 新的长度为原来的1.5倍或者为原来的长度加上minGrowth的长度
        int prefLength = oldLength + Math.max(minGrowth, prefGrowth); // might overflow
        if (0 < prefLength && prefLength <= SOFT_MAX_ARRAY_LENGTH) {
            return prefLength;
        } else {
            // put code cold in a separate method
            return hugeLength(oldLength, minGrowth);
        }
    }
	
	//超出长度调用的方法
    private static int hugeLength(int oldLength, int minGrowth) {
        int minLength = oldLength + minGrowth;
        if (minLength < 0) { // overflow
            throw new OutOfMemoryError(
                "Required array length " + oldLength + " + " + minGrowth + " is too large");
        } else if (minLength <= SOFT_MAX_ARRAY_LENGTH) {
            return SOFT_MAX_ARRAY_LENGTH;
        } else {
            return minLength;
        }
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值