java底层原理—ArrayList源码分析
引言
学习底层是为了更好的选择合适数据结构进行开发,这篇是为了讲解ArrayList底层原理的,同时也是总结一下自己的学习成果。
太多的文字让人看得眼花缭乱,废话不多说,上图解。
这是ArrayList的属性:
一、创建ArrayList对象,初始化过程
-
ArrayList<String> list = new ArrayList<>();
-
public ArrayList() { //this.当前数组=默认数组 this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
- 给当前存储数据的数组创建出来,创建完毕。
二、调用add方法,添加数据过程
-
list.add("admin");
-
public boolean add(E e) { ensureCapacityInternal(size + 1); //add方法把值"admin"传过来就是参数 e ,然后把值放进当前数组的下一个位置,但是我们这个当前数组还并没有被创建,我们就可以看看上面的方法 elementData[size++] = e; return true; }
-
执行
ensureCapacityInternal
方法private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); }
- 判断当前数组是否是空的元素数组(一般第一次都是)
- Math.max()方法是判断两个参数的大小,返回较大的值
- DEFAULT_CAPACITY是默认容量(10),一般第一次都是会返回默认容量
-
执行
ensureExplicitCapacity
方法private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); }
- 方法参数是最小容量
- 如果最小容量(将要开辟的元素空间大小) - 当前数组的长度 > 0 那么就证明空间大小不够,就会执行
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 + (oldCapacity >> 1) 的方式每次扩容1.5倍的容量
- 然后最后将当前数组给copy替换成新容量的数组,至此扩容完毕。
三、总结
- ArrayList底层使用数组进行存储数据
- ArrayList扩容机制每次扩容1.5倍