面试时别再回答ArrayList的初始容量为10了!!!这里有更好的答案!

使用过ArrayList或者背过面试题的小伙伴都知道ArrayList的初始容量为10
但这个答案不完全正确,在jdk1.2jdk1.6中的ArrayList的源码中,在构造方法上的确是创建了一个初始容量为10的容器。
摘录jdk_1.6的源码,1.2到1.6都是直接创建一个长度为10的数组
在这里插入图片描述
但是在jdk_1.7中的源码是这样写的
在这里插入图片描述
调用构造方法时,如下
在这里插入图片描述
说明从jdk_1.7开始,当你进行new ArrayList();创建的是一个空数组初始容量就不是10了,而是一个空数组


jdk_1.2开始到jdk_1.6,ArrayList都是直接创建了一个长度为10的数组。

是否有疑问jdk1.7初始容量为0,它是怎么进行扩容的?
jdk_1.7中的ArrayList定义了一个常量这个值就是10
在这里插入图片描述
这个常量在进行扩容的时候,会和当前容器的最小容量进行比较,取最大的作为新容器的容量
例如当你第一次调用add进行添加元素的时候,会触发扩容

public boolean add(E e) {
    
    
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

进入ensureCapacityInternal(size + 1);,一开始是一个空容器所以size=0传入的minCapacity=1

private void ensureCapacityInternal(int minCapacity) {
    
    
     if (elementData == EMPTY_ELEMENTDATA) {
    
    
         minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
     }
     ensureExplicitCapacity(minCapacity);
 }

会发现minCapacity被重新赋值为10 (DEFAULT_CAPACITY=10
传入ensureExplicitCapacity(minCapacity);这时minCapacity=10
下面是方法体:

private void ensureExplicitCapacity(int minCapacity) {
    
    
    modCount++;
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

modCount++是在父类AbstarctList中,
后又调用了扩容grow(10)

private void grow(int minCapacity) {
    
    
    int oldCapacity = elementData.length;// oldCapacity = 0
    int newCapacity = oldCapacity + (oldCapacity >> 1);// newCapacity = 0
    if (newCapacity - minCapacity < 0) // true
        newCapacity = minCapacity;// newCapacity = 10
    if (newCapacity - MAX_ARRAY_SIZE > 0) // false , MAX_ARRAY_SIZE =Integer.MAX_VALUE - 8;
        newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity);//创建了长度为10的数组
}

这是jdk1.7中的扩容机制代码
其中int newCapacity = oldCapacity + (oldCapacity >> 1);就是面试过程中经常提问到的,1.5倍原来数组的长度


再则ArrayList是允许自己设置初始容量的,调用带参数的构造方法即可,然后以这个初始容量按照1.5倍当前设置的初始容量进行扩容。

另外关于ArrayList的文章请看我其它几篇博客:

一文搞定ArrayList、LinkedList、HashMap、HashSet -----源码解读之ArrayList

你知道ArrayList哪几种情况下会报java.util.ConcurrentModificationException吗?

猜你喜欢

转载自blog.csdn.net/qq_41813208/article/details/107777539
今日推荐