首先,在调用add方法的时候 ,会去调用 ensureCapacityInternal 方法,传入一个参数 minCapacity 大小是size + 1,也就是现在我们需要的数组的最小的大小。
在ensureCapacityInternal 方法中,先判定一下elementdata是不是初始空数组
是的话就把minCapacity变动为默认容量 也就是10, 和传进来的minCapacity的最大值
之后调用 ensureExplicitCapacity 方法,把现在的minCapacity传进去- private void ensureCapacityInternal(int minCapacity) {
- if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
- minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
- }
- ensureExplicitCapacity(minCapacity);
- }
复制代码 第二步:
在这个ensureExplicitCapacity 方法中,会去判定一下传进来的minCapacity和当前elementdata的大小,如果需要的这个最小容量已经超过了当前数组的长度,就会去调用grow方法,也就是扩容的核心方法,并且把这个minCapacity传进去- private void ensureExplicitCapacity(int minCapacity) {
- modCount++;
- if (minCapacity - elementData.length > 0)
- grow(minCapacity);
- }
复制代码 第三步:
进入grow方法后,先去获取现在的elementdata的长度,并且先行扩容到1.5倍(这个>>1是位运算)。扩容后的容量记为 newCapacity ,用这个newCapacity 去和minCapacity也就是我们需要的最小的大小进行比较,还是达不到的话就让newCapacity=minCapacity。接着还要处理一下当前的newCapacity超过MAX_ARRAY_SIZE,也就是ArrayList允许的数组最大值的环境(一般是Integer.MAX_VALUE - 8)。调用hugeCapacity来进行处理,小于0的话就抛异常,超过最大值了就取最大值。最后调用Arrays.copyOf()方法。- private void grow(int minCapacity) {
- int oldCapacity = elementData.length;
- int newCapacity = oldCapacity + (oldCapacity >> 1); // 扩容到原来的 1.5 倍
- if (newCapacity - minCapacity < 0)
- newCapacity = minCapacity; // 若新容量仍不足,则取所需的最小容量
- if (newCapacity - MAX_ARRAY_SIZE > 0)
- newCapacity = hugeCapacity(minCapacity); // 检查是否超过最大允许大小
- elementData = Arrays.copyOf(elementData, newCapacity);
- }
复制代码- private static int hugeCapacity(int minCapacity) {
- if (minCapacity < 0) // overflow
- throw new OutOfMemoryError(); // 超出 int 最大值时抛出异常
- return (minCapacity > MAX_ARRAY_SIZE) ?
- Integer.MAX_VALUE : // 如果实际需求超大,则直接取 Integer.MAX_VALUE
- MAX_ARRAY_SIZE; // 否则取最大允许的数组大小
- }
复制代码 最后在这个Arrays.copyOf()方法中会创建一个新的数组,大小就是我们上一步得到并且传入的newCapacity。接着把旧数组中的元素拷贝到新数组中。- public static <T> T[] copyOf(T[] original, int newLength) {
- T[] copy = (T[]) Array.newInstance(original.getClass().getComponentType(), newLength);
- System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
- return copy;
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |