Ответ
Поведение зависит от конструктора, которым был создан Vector.
1. По умолчанию (удвоение):
Если Vector создан с начальной емкостью (capacity) 10 и без указания capacityIncrement, то при добавлении 11-го элемента его емкость удвоится (станет 20).
Vector<Integer> vec = new Vector<>(10); // capacity=10, capacityIncrement=0
for (int i = 0; i < 10; i++) vec.add(i); // size=10, capacity=10
vec.add(10); // Триггер увеличения. Новая capacity = 10 * 2 = 20
2. С заданным приращением:
Если Vector создан с указанием capacityIncrement, емкость увеличится на эту величину.
Vector<Integer> vec = new Vector<>(10, 5); // capacity=10, increment=5
for (int i = 0; i < 10; i++) vec.add(i); // size=10, capacity=10
vec.add(10); // Триггер увеличения. Новая capacity = 10 + 5 = 15
Принцип работы:
- Внутри
Vectorиспользует массив для хранения элементов. - Поле
capacityIncrementопределяет, на сколько увеличивать массив при переполнении. Если оно равно0, применяется стратегия удвоения. - Увеличение происходит автоматически при вызове методов добавления (
add,addElement), когдаsizeстановится равенcapacity.
Сравнение с ArrayList: ArrayList всегда увеличивает емкость примерно в 1.5 раза (старая емкость + старая емкость >> 1), и у него нет параметра capacityIncrement.
Ответ 18+ 🔞
А, слушай, вот эта штука с Vector, она же, блядь, как старая шкатулка с секретом — выглядит просто, а внутри механизм, ёпта! Сейчас разжуем, как он там раздувается, этот массив.
Ну, представь себе: ты создаёшь Vector. У него внутри, как у порядочной коллекции, есть массив, куда он элементы пихает. И есть два важных числа: capacity (сколько ячеек в массиве есть) и size (сколько из них уже занято). Пока size меньше capacity — всё спокойно, места хватает.
Но вот наступает момент, сука, когда ты пытаешься запихнуть элемент, а size уже равен capacity. Пиздец, места нет! Что делает Vector? Правильно, он идёт и создаёт новый, более просторный массив. А вот насколько более просторный — это, блядь, и есть главный фокус, и он зависит от того, как ты Vector создал!
Вариант первый, классический (удвоение):
Ты создал Vector просто так, или указал начальный размер, но не сказал, на сколько увеличивать. Внутри у него поле capacityIncrement становится равно нулю. Это, блядь, волшебная цифра! Когда приходит время расширяться, он берёт текущую вместимость и просто, нагло, удваивает её. Бах — и в два раза больше!
// Создал с начальной вместимостью 10. Приращение по умолчанию — 0.
Vector<Integer> vec = new Vector<>(10);
for (int i = 0; i < 10; i++) vec.add(i); // Пока всё ок, size=10, capacity=10
vec.add(10); // А тут пиздец, триггер! Места нет.
// Новая capacity = старая (10) * 2 = 20. Вот так вот, в рот меня чих-пых!
Вариант второй, контролируемый (приращение):
А если ты не доверяешь этой дикой арифметике с удвоением и хочешь всё контролировать? Пожалуйста! При создании Vector'а ты можешь указать вторым параметром — capacityIncrement. Это как шаг, на который он будет увеличиваться. Тогда, когда массив переполнится, он не будет охуевать и умножать на два, а просто прибавит этот самый шаг. Скромно и по делу.
// Создал с вместимостью 10 и шагом увеличения 5.
Vector<Integer> vec = new Vector<>(10, 5);
for (int i = 0; i < 10; i++) vec.add(i); // Опять size догнал capacity (10).
vec.add(10); // И снова триггер, ёпта!
// Новая capacity = старая (10) + шаг (5) = 15. Никаких неожиданностей.
А что там у его младшего брата, ArrayList?
О, это отдельная песня! ArrayList — он более хитрожопый. У него нет такого параметра, как capacityIncrement. Внутри он использует свою, блядь, фирменную формулу: старая ёмкость + (старая ёмкость >> 1). Сдвиг вправо на один бит — это, грубо говоря, деление на два. Получается, он увеличивает массив примерно в полтора раза. Не в два, как старый Vector по умолчанию, а именно в 1.5. Более экономно, что ли.
Так что запомни: Vector — это такой старый, предсказуемый дед. Либо в два раза вырастет, либо на заданную тобой величину. А ArrayList — более современный и хитрый тип, растёт всегда в полтора раза. Вот и вся магия, блядь, расширения массивов в этих коллекциях!