Ответ
Начальная ёмкость (capacity) внутреннего массива ArrayList при создании через конструктор без параметров равна 0, а не 10, начиная с Java 8. Массив создаётся лениво, при первом добавлении элемента.
Механизм работы:
- Конструктор
ArrayList(): Инициализирует внутренний массивelementDataпустой константойDEFAULTCAPACITY_EMPTY_ELEMENTDATA.// Java 8+ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; // {} (пустой массив) } - Первое добавление (
add(E e)): При первом вызовеadd()проверяется, является ли массив пустой константой. Если да, то ёмкость увеличивается до значенияDEFAULT_CAPACITY, которое равно 10.private static final int DEFAULT_CAPACITY = 10; - Последующее увеличение: Когда внутренний массив заполняется, его ёмкость увеличивается по формуле
newCapacity = oldCapacity + (oldCapacity >> 1), что примерно равно увеличению в 1.5 раза.
Конструкторы для явного указания ёмкости:
// Создаёт ArrayList с начальной ёмкостью 20
ArrayList<String> listWithCapacity = new ArrayList<>(20);
// Создаёт список, инициализированный другой коллекцией.
// Начальная ёмкость равна размеру переданной коллекции.
ArrayList<String> listFromCollection = new ArrayList<>(someOtherList);
Практические рекомендации:
- Избегайте дефолтного конструктора, если заранее известен примерный размер коллекции. Указание начальной ёмкости предотвращает многократные дорогостоящие операции копирования массива при росте.
size()vscapacity():size()возвращает количество элементов в списке, аcapacity()— длину внутреннего массива (этот метод private, но его логику можно понять).