Что будет если добавить еще один элемент при размере ArrayList 10?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Краткий ответ
При добавлении нового элемента в ArrayList с текущим размером (size) = 10 произойдет автоматическое увеличение внутреннего массива (обычно в 1.5 раза в стандартной реализации Java, или в ~1.6 раза в Android до API 33). Новый элемент будет успешно добавлен на 11-ю позицию (индекс 10), а размер коллекции станет равен 11. Никаких ошибок не возникнет — это одно из ключевых преимуществ ArrayList перед обычным массивом.
Подробное объяснение механизма
1. Исходное состояние
Предположим, у нас есть ArrayList<Integer>:
ArrayList<Integer> list = new ArrayList<>(10);
for (int i = 0; i < 10; i++) {
list.add(i); // заполняем 10 элементами
}
// Текущее состояние:
// size = 10
// capacity (емкость внутреннего массива) = 10
2. Добавление 11-го элемента
list.add(100); // Добавляем 11-й элемент
В этот момент происходит следующее:
Шаг 1: Проверка capacity
Метод add() вызывает внутреннюю функцию ensureCapacityInternal(size + 1). Система проверяет, достаточно ли места во внутреннем массиве elementData для нового элемента.
Шаг 2: Расширение массива (при необходимости)
Поскольку текущий размер size (10) равен capacity (10), свободных ячеек нет. Запускается процесс расширения (resize):
// Упрощенная логика из исходного кода Android/Java:
int newCapacity = oldCapacity + (oldCapacity >> 1); // Увеличиваем в ~1.5 раза
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
elementData = Arrays.copyOf(elementData, newCapacity);
Для начальной емкости 10:
oldCapacity = 10newCapacity = 10 + (10 >> 1) = 10 + 5 = 15- Создается новый массив размером 15 элементов
- Все 10 существующих элементов копируются в новый массив
- Старый массив становится доступен для сборщика мусора
Шаг 3: Непосредственное добавление
elementData[size] = newElement; // size = 10
size = size + 1; // теперь size = 11
3. Особенности реализации
Коэффициент расширения:
- Java (стандартная реализация OpenJDK): ×1.5 (старая емкость + старая емкость / 2)
- Android до API 33: ×1.6 (старая емкость + (старая емкость >> 2) + 6)
- Android API 33+: соответствует реализации OpenJDK (×1.5)
Важные нюансы:
-
Временная сложность: В обычном случае добавление имеет сложность O(1), но при расширении массива — O(n), так как требуется копирование всех существующих элементов.
-
Initial Capacity: Если бы
ArrayListбыл создан с дефолтной емкостью (10) и мы добавили 11 элементов, произошло бы несколько расширений:- При добавлении 11-го элемента: 10 → 15
- При добавлении 16-го элемента: 15 → 22
- И так далее...
-
Оптимизация: Если заранее известно количество элементов, лучше задать начальную емкость:
// Избегаем многократных расширений
ArrayList<Integer> list = new ArrayList<>(100);
Практический пример
ArrayList<String> cities = new ArrayList<>(10);
System.out.println("Initial capacity: " + getCapacity(cities)); // 10
// Заполняем 10 элементами
for (int i = 0; i < 10; i++) {
cities.add("City " + i);
}
// Добавляем 11-й элемент
cities.add("Moscow");
System.out.println("Size after adding 11th element: " + cities.size()); // 11
System.out.println("Capacity after expansion: " + getCapacity(cities)); // 15
System.out.println("11th element: " + cities.get(10)); // "Moscow"
Сравнение с аналогичными структурами
- Обычный массив: Вызовет
ArrayIndexOutOfBoundsException - LinkedList: Просто создаст новый узел, без расширения массива
- Vector: Аналогично ArrayList, но увеличение вдвое (×2.0) и синхронизировано
Вывод
Добавление элемента в ArrayList при достижении текущего предела емкости — штатная операция, которую разработчику можно не отслеживать вручную. Однако для оптимизации производительности в сценариях с большим количеством элементов стоит:
- Задавать начальную емкость через конструктор
- Использовать
ensureCapacity()при пакетном добавлении - Помнить о временных затратах на копирование при расширении
Это поведение делает ArrayList идеальным выбором для сценариев, где требуется частый доступ по индексу и динамическое изменение размера, но известен примерный диапазон количества элементов.