集合-ArrayList扩容机制

2019-08-19  本文已影响0人  512DIDIDI
引言

ArrayList是基于数组所实现的。
众所周知,数组是不能进行扩容操作的,而我们调用ArrayList的add()等方法时却可以实现扩容操作。

源码

其内部源码主要经历以下步骤:

public boolean add(E e) {
  ensureCapacityInternal(size + 1); 
  elementData[size++] = e;
  return true;
}
private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
    modCount++;
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}
private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity);
}
总结

ArrayList实现扩容操作的机制,就是在超过elementData数组长度时,将数组扩容1.5倍,并调用Arrays.copyOf复制到新数组。而至于1.5倍的扩容,是因为不会导致每次进行add操作时就要频繁进行扩容数组长度,也不会过于浪费内存空间。当然,如果我们能预知ArrayList的大小时,我们应该调用ensureCapacity()方法来事先扩容数组长度,避免频繁扩容影响性能。

public void ensureCapacity(int minCapacity) {
    int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
        ? 0
        : DEFAULT_CAPACITY;
    if (minCapacity > minExpand) {
        ensureExplicitCapacity(minCapacity);
    }
}
扩展知识
上一篇下一篇

猜你喜欢

热点阅读