ArrayList内部实现原理
ArrayList内部实现原理
首先,我们new一个对象list集合
List<String> list = new ArrayList<>();
我们知道对象的创建离不开构造方法,因此我们查看ArrayList源码的时候先看其构造方法
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
transient Object[] elementData; // non-private to simplify nested class access
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
通过源码我们发现在new ArrayList<>()的时候,其实质是获得一个Object[]数组;
因此ArrayList的本质就是一个数组
然后我们向元素中添加一个对象通过add()方法,并查看add的源码
list.add("123");
private int size;
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
在add方法中调用了一个方法ensureCapacityInternal()用来初始化容量
然后向数组的末尾添加了一个元素
接下来我们来看看这个ensureCapacityInternal()方法的内部是如何实现的
private static final int DEFAULT_CAPACITY = 10;
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
很显然在ArrayList被创建的时候执行了this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;,因此if语句是成立的,我们知道当我们第一次执行add("123")的时候size=0,因此该方法的参数是1。所以minCapacity=10
然后我们看ensureExplicitCapacity(minCapacity);这个方法的内部。
protected transient int modCount = 0;
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
因为elementData是一个null的对象数组,所以elementData.length=0,if条件成立执行grow(minCapacity)
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
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);
}
因为minCapacity=0,所以newCapacity=0,导致if(newCapacity - minCapacity<0)成立,结果newCapacity = minCapacity;等于10;
MAX_ARRAY_SIZE= Integer.MAX_VALUE - 8;可以认为MAX_ARRAY_SIZE是一个无穷大的数,因此if (newCapacity - MAX_ARRAY_SIZE > 0)语句不成立,elementData = Arrays.copyOf(elementData, newCapacity);拷贝原数组到新数组,新数组长度为10;
当我们继续添加直到ArrayList的size=10,我们继续add第11个对象的时候if (minCapacity - elementData.length > 0)成立,
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
因此,当ArrayList容量存满的时候,会扩容为原来的3/2倍
通过内部原理可知,对于ArrayList的每次操作,当需要扩容的时候,每次扩容为当前长度的1.5倍,但是每次操作集合都需要进行数组的拷贝,此过程消耗资源,所以如果对于经常对集合进行添加删除操作的时候,不建议使用ArrayList

本文来自博客园,作者:StepForwards,转载请注明原文链接:https://www.cnblogs.com/forwards/p/7544960.html

浙公网安备 33010602011771号