ArrayList底层原理
ArrayList在工作中经常用到,今天来看一下ArrayList的底层是如何实现的?在这之前,先抛出几个问题。
1.ArrayList底层实现的数据结构是什么?
2.ArrayList的初始化容量是多少,底层的扩容机制是什么?
3.ArrayList是在什么时候初始化容量的?
4.ArrayList是如何实现添加元素操作的?
//实现了List接口,实现了List的常用方法,如add(E e)
//实现了RandomAccess接口,这是个标记接口,接口中没有任何方法,作用只是标记ArrayList可以支持快速随机访问
//实现了Cloneable接口,表示ArrayList实例调用clone()可以克隆一个和自己一样的实例(这里是浅拷贝)。
//实现了Serializable接口,表示可以序列化和反序列化,可以在网络中传输。
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L;
//默认容量是10
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//底层使用Object数组实现的,所有可以存任何类型
transient Object[] elementData;
private int size;
//代码太多,省略......
}
下面代码是ArrayList添加一个元素的底层实现
这两行代码,底层帮我们做了什么?debug进去看看
ArrayList arrayList = new ArrayList<>();
arrayList.add(new String("I am xiao qiang"));
首先是类加载器,他的作用是将class文件加载到jvm虚拟机中
接着进入到了ArrayList的构造方法中,可以看到构造方法给elementData赋了一个空值,说明此时仅仅创建一个ArrayList对象,除此之外没有做任何事情。
这也说明,我们只是创建了ArrayList对象,它并没有初始化容量。
接下来dubug进入到了add()方法中
进入到String的构造方法中,创建出String字符串对象,并赋值“I am xiao qiang”
继续debug,终于执行了ArrayList的add()方法,ensureCapacityInternal是判断是否要扩容的方法,进入该方法
可以看到底层是调用了一个计算容量的方法calculateCapacity,然后将默认容量10返回了,这说明ArrayList容量的初始化是在添加元素add()方法后进行的
接着继续执行add()方法,elementData[0]被赋值成"I am xiao qiang"
到此,两行代码终于结束了。
下面我们看一下ArrayList扩容机制的代码。
如果minCapacity的值大于add数据之前的大小,就调用grow方法,进行扩容,否则什么也不做。
下面是具体看出来扩容机制的大小增长规则了:
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
//oldCapacity >> 1就是1/2 oldCapacity
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);
}
注意:这里传过来的minCapcatiy的值是size+1,能够实现grow方法调用就肯定是(size+1)>elementData.length的情况,所以size就是初始最大容量或上一次扩容后达到的最大容量,所以才会进行扩容。newCapacity=oldCapacity+(oldCapacity>>1),这里就是扩容大小确定的地方,相当于新的最大容量是 size+1+size/2 相当于原来的1.5倍然后加1
最新大厂IT课程:点击获取