Давайте посмотрим на этот код (jdk1.8)
@Test
public void testArraySize() throws Exception {
List<String> list = new ArrayList<>();
list.add("ds");
list.add("cx");
list.add("cx");
list.add("ww");
list.add("ds");
list.add("cx");
list.add("cx");
list.add("ww");
list.add("ds");
list.add("cx");
list.add("last");
}
1) Поместите точку останова в строку, когда вставлено «последнее»
2) Перейти к методу добавления ArrayList
Вы увидите
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
3) Перейдите к методу ОбеспечитьCapacityInternal, вызов этого метода ensureExplicitCapacity
4)
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
return true;
В нашем примере minCapacity равен 11 11-10 > 0
, поэтому вам необходим grow
метод
5)
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) oldCapacity
= 10, поскольку мы не указали этот параметр при инициализации ArrayList
, поэтому он будет использовать емкость по умолчанию (10)
2) int newCapacity = oldCapacity + (oldCapacity >> 1);
Здесь newCapacity равен oldCapacity плюс oldCapacity со смещением вправо на единицу
(oldCapacity is 10
это двоичное представление 00001010
, сдвинув его на один бит вправо, мы получим 00000101
, что равно 5 в десятичном выражении, поэтому newCapacity
равно 10 + 5 = 15
)
3)
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
Например, ваша емкость инициализации равна 1, когда вы добавите второй элемент в arrayList newCapacity
будет равно 1(oldCapacity) + 0 (moved to right by one bit) = 1
В этом случае newCapacity меньше minCapacity и elementData
(объект массива внутри arrayList) не может содержать новый элемент, поэтому newCapacity равен minCapacity
4)
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
Проверьте, не достигает ли размер массива MAX_ARRAY_SIZE (который равен Integer.MAX - 8) Почему максимальный размер массива ArrayList равен Integer.MAX_VALUE - 8?
5) Наконец, он копирует старые значения в newArray длиной 15