一.概述对于Java开发来说,使用集合是很常见的,其中ArrayList大概用的比较多,用起来也挺简单的。通常,它是一个新的数组列表,然后向它添加元素,但是当你向它添加元素时,你真的知道它
一.概述
对于Java开发来说,使用集合是很常见的,其中ArrayList大概用的比较多,用起来也挺简单的。通常,它是一个新的数组列表,然后向它添加元素,但是当你向它添加元素时,你真的知道它内部发生了什么吗?
二、源代码解读
1.相关内部参数DEFAULT_CAPACITY:默认初始容量EMPTY_ELEMENTDATA:空默认实例对象数组DEFAULT CAPACITY _ EMPTY_ELEMENTDATA:类似于EMPTY _ element data,对象数组大小:实际包含的元素个数size:ArrayList
2 .构造器
ArrayList()
当执行第一行代码时,有以下操作:
就是将ArrayList的elementData引用指向内置的默认对象数组。
公共数组列表(int initialCapacity)
如果传入的容量大小大于0,则将内置的elementData指向一个新的Object数组(数组大小为initialCapacity)如果initialCapacity值为0,则将elementData引用指向EMPTY_ELEMENTDATA这个内部Object数组。如果以上两者均不满足的话,则会抛出IllegalArgumentException并附带initialCapacity参数。
3.加法分析
添加(E,E)
我们先来看这个方法。
让我们跳过第一行代码,看第二行。它的作用是将elementData数组中size++位置的元素指定为传入参数。一开始我们知道size是数组的实际大小,非常好理解。在它执行size++之后,elementData[size]++的位置是数组中的最后一个位置。所以有结尾添加的效果。添加成功后,第三行返回true,没什么好说的。关键是看第一行,ensureCapacityInternal的方法,代码如下:
private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); }
首先,确定elementData是否存储了空数组。如果是,则所需能力是默认能力,即10。接下来,执行AssureExplicitSpace来确定它是否需要扩展。让我们来看看这个方法:
private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code 注意这个注释 if (minCapacity - elementData.length > 0) grow(minCapacity); }
显然,增长法就是扩张法。什么时候实施?也就是说,当所需的最小容量大于当前存储数组的长度时,需要对其进行扩展。有一个地方需要考虑,即minCapacity & # 8211elementData.length & gt0可以改成min capacity >:element data . length的拼写怎么样?
让我们再来看看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); }
这里,首先获取现有阵列的容量,然后将该值扩展1.5倍,以获得新的容量值(旧容量>:& gt这个右移1除以2),然后确定扩展的容量是否小于所需的最小容量。如果是,则将最小容量分配给新容量值,否则,确定新容量值是否大于MAX_ARRAY_SIZE值。如果是,则将hugeCapacity的返回值赋给新的容量值。让我们来看看hugeCapacity方法:
private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
这里可以看到,如果要求的最小容量小于0,则抛出异常;否则,如果所需的最小容量大于MAX_ARRAY_SIZE,则为整数。取MAX _ VALUE否则,将采用MAX_ARRAY_SIZE。
这是arrayList执行Add的过程。如果构造时没有参数,则初始数组容量为0。当实际添加阵列时,容量才真正得到分配。按照每次1.5倍(位操作)的比例,借助copeOf进行扩容。