ArrayList扩容机制、底层源码解读
-
ArrayList的底层操作机制源码分析
-
ArrayList中维护了一个Object类型的数组elementData ;transient Object[] elementData; //transient 表示瞬间,短暂的,表示该属性不会被序列号 -
当创建对象是,如果使用的是无参构造器,则初始elementData容量为0(jdk7是10) -
当添加元素时,先判断是否需要扩容,如果需要扩容,则条用grow方法,否则直接添加元素到合适位置 -
如果使用的是无参构造器,如果第一次添加,需要扩容的话,则扩容elementData为10,如果需要再次扩容的话,则扩容elementData为1.5倍 -
如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData为1.5倍。
import java.util.ArrayList;
?
public class ArraylistSource {
? ?public static void main(String[] args) {
?
? ? ? ?//使用无参构造器创建ArrayList对象
? ? ? ?ArrayList arrayList = new ArrayList();
// ? ? ? ArrayList arrayList = new ArrayList(8); //指定构造器大小为8
?
? ? ? ?//使用for循环给arrayList集合添加1-10数据
? ? ? ?for (int i = 0; i < 10; i++) {
? ? ? ? ? ?arrayList.add(i);
? ? ? }
? ? ? ?for (int i = 11; i < 15; i++) {
? ? ? ? ? ?arrayList.add(i);
? ? ? }
? ? ? ?arrayList.add(100);
? ? ? ?arrayList.add(200);
? ? ? ?arrayList.add(null);
? ? ? ?System.out.println(arrayList);
? }
}
/*
源码分析:
? ?//创建一个空数组
? ?public ArrayList() {
? ? ? ?this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
? ?}
?
? ?//执行ArrayList.add():先确定是否要扩容,然后在执行 赋值
? ?public boolean add(E e) {
? ? ? ?ensureCapacityInternal(size + 1); // Increments modCount!!
? ? ? ?elementData[size++] = e;
? ? ? ?return true;
? ?}
?
? ?//确定minCapaccity:第一次扩容为10
? ?private void ensureCapacityInternal(int minCapacity) {
? ? ? ?ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
? ?}
?
? ?//modCount++ 记录集合被修改的次数;如果elementData的大小不够,就调用grow()去扩容
? ?private void ensureExplicitCapacity(int minCapacity) {
? ? ? ?modCount++;
?
? ? ? ?// overflow-conscious code
? ? ? ?if (minCapacity - elementData.length > 0)
? ? ? ? ? ?grow(minCapacity);
? ?}
?
? ?//真的扩容;使用扩容机制来确定要扩容到多大;第一次newCapacity = 10 ; 第二次及其以后,按照1.5倍扩容;扩容使用的量Arrays.copyOf()
? ?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);
? ?}
? ?
? ?//运行结果:
? ?[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 100, 200, null]
*/
|