Емкость, как вы ее описали - непрерывная память, выделенная для ArrayList для хранения значений. ArrayList хранит все значения в массиве и автоматически изменяет размер массива для вас. Это приводит к накладным расходам на управление памятью при изменении размера.
Если я правильно помню, Java увеличивает размер резервного массива ArrayList с размера N до размера 2N + 2, когда вы пытаетесь добавить еще один элемент, который может занять емкость. Я не знаю, к какому размеру он увеличивается, когда вы используете метод insert
(или аналогичный) для вставки в определенное положение за пределами емкости или даже разрешает ли это.
Вот пример, который поможет вам подумать о том, как это работает. Изобразите каждый пробел между |
s как ячейку в массиве поддержки:
| | |
размер = 0 (не содержит элементов), емкость = 2 (может содержать 2 элемента).
|1| |
размер = 1 (содержит 1 элемент), емкость = 2 (может содержать 2 элемента).
|1|2|
размер = 2, емкость = 2. Добавление другого элемента:
|1|2|3| | | |
размер увеличен на 1, емкость увеличена до 6 (2 * 2 + 2). Это может быть дорого с большими массивами, так как выделение большой смежной области памяти может потребовать небольшой работы (в отличие от LinkedList, который выделяет много маленьких фрагментов памяти), потому что JVM должен искать подходящее местоположение и может попросить у ОС больше памяти. Также дорого копировать большое количество значений из одного места в другое, что будет сделано после обнаружения такого региона.
Мое эмпирическое правило таково: если вы знаете емкость, которая вам потребуется, используйте ArrayList, потому что будет только одно распределение, и доступ будет очень быстрым. Если вы не знаете требуемой емкости, используйте LinkedList, поскольку добавление нового значения всегда требует одинакового объема работы, и копирование не требуется.