Я думаю, что метод trimToSize()
в Java ArrayList не нужен. Насколько я понимаю:
Возьмем массив целых чисел:
int[] a = new int[10]; //This allocates ten free slots proactively.
Основным преимуществом ArrayList является то, что он может создавать массивы динамически во время выполнения, что позволяет экономить память. Теперь код ArrayList<Integer> arl = new ArrayList<Integer>(10);
не будет назначать десять свободных слотов заранее; вместо этого он добавляет слоты только тогда, когда есть данные для хранения.
Теперь в спецификации Java сказано, что trimToSize()
удалит неиспользуемое пространство из ArrayList, но, как я понимаю, в ArrayList не будет неиспользуемого пространства, потому что пространство создается только тогда, когда данные доступны, а когда данные доступны, неиспользуемое или свободного места будет ноль.
2 ответа
Ваше понимание неверно. Если вы создаете new ArrayList<Integer>(10)
, он создаст массив целых чисел размера 10, заполненный нулями внутри ArrayList в качестве ядра своей модели данных. Он заполнит некоторые или все слоты в зависимости от количества элементов и увеличит размер базового массива, если количество элементов превысит его возможное количество. Актуален метод trimToSize()
.
10
, например. Integer[10]
. Неиспользуемое пространство считается пустым, но выделяется. Необходимость повторного копирования всех данных в новый массив при каждой вставке потребовала бы огромного количества вычислений.
Избыточный: нет. Полезный? Только в очень специфических ситуациях.
Что вы должны знать, так это то, что ArrayList
увеличивает массив поддержки, когда он заполнен определенным соотношением элементов.
[то, что здесь стояло раньше, использовалось для Map
, а не ArrayList
]
ArrayList
внутренне будет проверять каждый раз, когда добавляется элемент, следует ли изменять размер массива поддержки:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
}
private void ensureCapacityInternal(int minCapacity) {
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
elementData = Arrays.copyOf(elementData, newCapacity);
}
Я не учел некоторые вещи, которые в основном были пограничными проверками. Итак, как видите: когда заканчивается место для добавления элемента, он создает новый массив в 1,5 раза больше предыдущего и добавляет в него все элементы. При начальном значении 10 элементов, после этого сразу же будет 15.
Экстраполируйте это на гораздо более высокие значения, и вы увидите, что вы внезапно начинаете выделять тысячи пустых записей массива, когда вы, возможно, закончили с добавлением элементов.
Точно так же удаление значений может привести к тому, что ваш резервный массив из 10 миллионов элементов сократится до 10 элементов. Довольно расточительно выделять несколько миллионов записей массива, когда вам нужно всего лишь дюжина.
Похожие вопросы
Новые вопросы
java
Java — это высокоуровневый объектно-ориентированный язык программирования. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег часто используется вместе с другими тегами для библиотек и/или фреймворков, используемых разработчиками Java.
new ArrayList<Integer>(10)
делал с этим аргументом10
, если не предварительно выделял 10 слотов?