Я думаю, что метод 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 не будет неиспользуемого пространства, потому что пространство создается только тогда, когда данные доступны, а когда данные доступны, неиспользуемое или свободного места будет ноль.

3
user1613360 3 Июн 2014 в 06:18
2
ArrayList на самом деле выделяет значительно больше места, чем ему нужно, каждый раз, когда он заканчивается, поэтому ему не нужно будет выделять сразу, когда он снова увеличивается.
 – 
user2357112
3 Июн 2014 в 06:21
1
Кстати, как вы думаете, что new ArrayList<Integer>(10) делал с этим аргументом 10, если не предварительно выделял 10 слотов?
 – 
user2357112
3 Июн 2014 в 06:22
уходит, так как @user2357112 дважды подряд просмотрел его комментарий
 – 
Rogue
3 Июн 2014 в 06:23

2 ответа

Лучший ответ

Ваше понимание неверно. Если вы создаете new ArrayList<Integer>(10), он создаст массив целых чисел размера 10, заполненный нулями внутри ArrayList в качестве ядра своей модели данных. Он заполнит некоторые или все слоты в зависимости от количества элементов и увеличит размер базового массива, если количество элементов превысит его возможное количество. Актуален метод trimToSize().

9
Hovercraft Full Of Eels 3 Июн 2014 в 06:20
Нет, я не думаю, что это правильно, массив размером 10 может хранить десять элементов, но он не будет выделен без доступных данных.
 – 
user1613360
3 Июн 2014 в 06:24
1
Базовый массив будет иметь размер 10, например. Integer[10]. Неиспользуемое пространство считается пустым, но выделяется. Необходимость повторного копирования всех данных в новый массив при каждой вставке потребовала бы огромного количества вычислений.
 – 
Rogue
3 Июн 2014 в 06:26
2
@user1613360: Вот исходный код версии Java 7. Прочтите его, и вы увидите, что он действительно выделяет 10 слотов.
 – 
user2357112
3 Июн 2014 в 06:27

Избыточный: нет. Полезный? Только в очень специфических ситуациях.

Что вы должны знать, так это то, что 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 элементов. Довольно расточительно выделять несколько миллионов записей массива, когда вам нужно всего лишь дюжина.

5
Jeroen Vannevel 3 Июн 2014 в 06:40
1
ArrayLists не имеют коэффициентов загрузки. Вы думаете о HashMaps.
 – 
user2357112
3 Июн 2014 в 06:27
Списки массивов начинаются с 10 (или 15, но 15 может быть для карт или наборов) и каждый раз удваиваются.
 – 
Anubian Noob
3 Июн 2014 в 06:35
@AnubianNoob: он начинается с 10, но я считаю, что он становится только на 150% новым размером, а не удваивается.
 – 
Jeroen Vannevel
3 Июн 2014 в 06:36