← Назад к вопросам
Почему массив не расширяется?
1.2 Junior🔥 191 комментариев
#ORM и Hibernate#Spring Boot и Spring Data#Базы данных и SQL
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Почему массив не расширяется?
Природа массивов в Java
Массив в Java — это фиксированная структура данных с неизменяемым размером. Это одна из ключевых особенностей, которую нужно понимать при работе с Java.
Когда ты создаёшь массив, в памяти выделяется строго определённое количество ячеек. После этого размер массива никогда не может измениться.
int[] numbers = new int[5]; // Создаём массив на 5 элементов
numbers[0] = 10;
numbers[4] = 50;
// numbers[5] = 60; // ❌ ArrayIndexOutOfBoundsException - выход за границы
Почему это сделано так?
Причина 1: Производительность
- Фиксированный размер позволяет Java точно знать, сколько памяти выделить
- Доступ к элементу по индексу работает за O(1) благодаря адресной арифметике
- Нет накладных расходов на динамическое расширение
Причина 2: Предсказуемость
- Программист явно контролирует размер массива
- Нет неожиданных выделений памяти во время работы программы
Причина 3: Простота
- Массивы — примитивный тип, близкий к памяти компьютера
- Прямое отображение на Си-подобные массивы
Что происходит, если нужна расширяемая коллекция?
Для этого существуют классы-обёртки:
// ❌ Неправильно - массив не расширяется
int[] numbers = new int[5];
// После 5 элементов ничего не поместится
// ✅ Правильно - используем ArrayList
List<Integer> numbers = new ArrayList<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);
// И так можно добавлять столько, сколько нужно
ArrayList внутри использует массив, но автоматически расширяет его при необходимости:
public class ArrayList<E> extends ... {
private Object[] elementData; // Внутренний массив
private int size;
public void add(E e) {
ensureCapacity(size + 1); // Проверяем, нужно ли расширение
elementData[size++] = e;
}
private void ensureCapacity(int minCapacity) {
if (minCapacity > elementData.length) {
// Создаём новый массив большего размера (обычно 1.5x)
Object[] newArray = new Object[newCapacity];
System.arraycopy(elementData, 0, newArray, 0, size);
elementData = newArray;
}
}
}
Другие расширяемые коллекции
- LinkedList — для частого добавления/удаления в начало/конец
- HashMap — для пар ключ-значение
- HashSet — для уникальных элементов
Практический пример: ошибка при работе с массивом
int[] arr = new int[3];
arr[0] = 100;
arr[1] = 200;
arr[2] = 300;
// arr[3] = 400; // ❌ ArrayIndexOutOfBoundsException
// Правильное решение:
List<Integer> list = new ArrayList<>(Arrays.asList(100, 200, 300));
list.add(400); // ✅ Работает
Преобразование массива в расширяемую коллекцию
int[] arr = {1, 2, 3};
// Способ 1: преобразование
List<Integer> list = new ArrayList<>(Arrays.asList(
Arrays.stream(arr).boxed().toArray(Integer[]::new)
));
// Способ 2: создать новый ArrayList и добавить элементы
List<Integer> list2 = new ArrayList<>();
for (int num : arr) {
list2.add(num);
}
Запомни
- Массив — фиксированный размер, это по дизайну Java
- ArrayList — расширяемая коллекция, использует массив внутри
- Выбирай инструмент в зависимости от задачи
- При выходе за границы выбросится
ArrayIndexOutOfBoundsException - Производительность: массив быстрее, но ArrayList удобнее