ArrayList源码讲解
时间:2021-02-18 13:31:47
收藏:0
阅读:0
ArrayList源码
-
以ArrayList的add()方法为例
/** * 新增元素操作 */ // eg1:第一次新增元素e="a1", public boolean add(E e) { /** 确定是否需要扩容,如果需要,则进行扩容操作*/ ensureCapacityInternal(size + 1); // Increments modCount!! // eg1:size=0,elementData[0]="a1",然后a自增为1 elementData[size++] = e; return true; }
-
方法很简单,先扩容,再维护 size 变量 ,接着往里填元素。而添加方法中的扩容方法如下:
// eg1:第一次新增元素,所以size=0,则:minCapacity=size+1=1,DEFAULT_CAPACITY=10 private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { // eg1:第一次新增元素,minCapacity取最大值10 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); }
-
此时可以发现方法中又调用了其他方法:继续跟踪
/** * 确保明确的ArrayList的容量 * * @param minCapacity ArrayList所需的最小容量 */ // eg1:第一次新增元素,minCapacity=10 private void ensureExplicitCapacity(int minCapacity) { // eg1: modCount++后,modCount=1 modCount++; /** 如果所需的最小容量大于elementData数组的容量,则进行扩容操作 */ if (minCapacity - elementData.length > 0) { // eg1:10-0=10,满足扩容需求 // eg1:minCapacity=10 grow(minCapacity); } }
-
最后发现,真正的扩容操作在于 grow() 方法里:
/** * Increases the capacity to ensure that it can hold at least the * number of elements specified by the minimum capacity argument. * * 扩容操作 * * @param minCapacity 所需要的最小扩容量 */ // eg1:第一次新增元素,minCapacity=10,即:需要将elementData的0长度扩容为10长度。 private void grow(int minCapacity) { /** 原有数组elementData的长度*/ int oldCapacity = elementData.length; // eg1:oldCapacity=0 /** * A >> 1 等于 A/2 * eg: 3 >> 1 = 3/2 = 1 * 4 >> 1 = 4/2 = 2 * ------------------------ * A << 1 等于 A*2 * eg: 3 << 1 = 3*2 = 6 * 4 << 1 = 4*2 = 8 * * 000100 >> 1 = 000010 * 000100 << 1 = 001000 */ /** 新增oldCapacity的一半整数长度作为newCapacity的额外增长长度 */ int newCapacity = oldCapacity + (oldCapacity >> 1); // eg1:newCapacity=0+(0>>1)=0 /** 新的长度newCapacity依然无法满足需要的最小扩容量minCapacity,则新的扩容长度为minCapacity */ if (newCapacity - minCapacity < 0) { // eg1:newCapacity=10 newCapacity = minCapacity; } /** 新的扩容长度newCapacity超出了最大的数组长度MAX_ARRAY_SIZE */ if (newCapacity - MAX_ARRAY_SIZE > 0) { newCapacity = hugeCapacity(minCapacity); } /** 扩展数组长度为newCapacity,并且将旧数组中的元素赋值到新的数组中 */ // eg1:newCapacity=10, 扩容elementData的length=10 elementData = Arrays.copyOf(elementData, newCapacity); }
-
hugeCapacity() 方法解析:
/** * The maximum size of array to allocate. * Some VMs reserve some header words in an array. * Attempts to allocate larger arrays may result in * OutOfMemoryError: Requested array size exceeds VM limit * * 要分配的数组的最大大小。一些vm在数组中保留一些头字。 * 尝试分配较大的数组可能会导致OutOfMemory错误:请求的数组大小超过了虚拟机限制 */ // MAX_ARRAY_SIZE=2147483639=01111111 11111111 11111111 11110111 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; //最大限度容量 private static int hugeCapacity(int minCapacity) { if (minCapacity < 0)//溢出 throw new OutOfMemoryError(); //如若需要扩容的量大于了最大限制,则扩容量改为 int 最大限制量:2147483647。 //否则为本类中所限制长度:2147483647-8 return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
-
总结
评论(0)