ArrayList扩容原理——面试题
2020-07-21 04:09
1376 查看
下面,我们从源码来慢慢来刨析:
首先,我们来看看ArrayList类定义的源码:
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
可以看到ArrayList继承了AbstractList类,以及其他的接口。
然后,我们来看看ArrayList里面的三个构造函数(此处着重分析前两个)
1. 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); } } 2. public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
第一个构造函数是带参的,参数是容量大小,作用是在定义ArrayList时给定了初始数组大小,设为空数组;第二个构造函数是无参的,设置数组初始大小是10,空数组。注:调用默认的构造函数时数组初始化大小为0。
那么,我们再来看看,ArrayList扩容核心方法add:
public boolean add(E e) {//size为数组内元素的个数;容量为数组的长度 ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } //确保数组扩容到指定大小 private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } private static int calculateCapacity(Object[] elementData, int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity; } private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); }
我们可以从add方法看到,ArrayList扩容分两步:
1.扩大容量
2.添加元素
add方法是主体,下面三个方法是为了实现扩容的。最后一个方法里调用了grow方法,那么下面我们来看看grow方法的定义:
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: elementData = Arrays.copyOf(elementData, newCapacity); }
可以看到,扩大以后的新的容量的计算方式:
旧的容量+旧容量的一半(>>右移运算符,相当于oldCapacity除以2的一次方),即扩大为旧容量的1.5倍;如果大于了最大数组大小,用最大数组处理(此处是调用的hugeCapacity方法)
我们可以看到扩容里重要的一步是:扩大容量之后,将原来的数组copy到扩大后的容量中,这里调用了copyOf方法。
相关文章推荐
- ArrayList 扩容原理
- ArrayList的add()扩容原理
- ArrayList扩容原理
- ArrayList自动扩容机制(底层原理)
- ArrayList扩容原理,源码分析
- 你注意ArrayList扩容原理了吗
- 浅析ArrayList源码(二)————add方法分析以及扩容原理
- ArrayList扩容引起效率降低问题的原理
- ArrayList 原理、 扩容机制
- ArrayList、Vector、HashMap、HashSet的默认初始容量、加载因子、扩容增量底层原理
- 深入java集合学习2-ArrayList的实现原理
- 面试题 HashMap 原理
- ArrayList扩容分析
- ArrayList的实现原理
- ArrayList的原理和特点
- ArrayList 的扩容机制
- 【Java集合】ArrayList的使用及原理
- ArrayList实现原理
- Java集合学习:ArrayList的实现原理
- (转载)关于ArrayList的5道面试题