Емкость ArrayList [дубликат]

Возможный дубликат:
Как получить емкость ArrayList в Java?

Как найти емкость ArrayList ?

31
задан Community 23 May 2017 в 12:34
поделиться

8 ответов

Интересно, для чего он тебе нужен? Вы должны знать, что емкость не является (как может показаться) верхним пределом того, сколько вы можете поместить в ArrayList. Это значение, представляющее, сколько данных вы можете поместить в список, не заставляя его перераспределять внутренний массив. По сути, понятие емкости существует только для того, чтобы вы могли немного настроить производительность.

В любом случае, возможно, вы уже это знаете, так что вот собственно ответ.

Интерфейс, предоставляемый API для ArrayList, просто не поддерживает такой вариант использования. Существует много причин для этого. Одна из причин заключается в том, что вы не должны заботиться об этом. ArrayList следует рассматривать как неограниченный массив, который абстрагируется от таких деталей, как емкость.

Ближе всего к управлению емкостью можно подойти с помощью конструктора ArrayList(int initialCapacity) и двух методов trimToSize() и ensureCapacity(int minCapacity) .

Однако для развлечения мне удалось решить эту проблему с помощью уродливого отражения (не используйте это):

import java.lang.reflect.Field;
import java.util.ArrayList;
public class Test {

    public static void main(String[] args) throws Exception {
        ArrayList<Integer> list = new ArrayList<Integer>(3);
        for (int i = 0; i < 17; i++) {
            list.add(i);
            System.out.format("Size: %2d, Capacity: %2d%n",
                              list.size(), getCapacity(list));
        }
    }

    static int getCapacity(ArrayList<?> l) throws Exception {
        Field dataField = ArrayList.class.getDeclaredField("elementData");
        dataField.setAccessible(true);
        return ((Object[]) dataField.get(l)).length;
    }
}

Вывод:

Size:  1, Capacity:  3
Size:  2, Capacity:  3
Size:  3, Capacity:  3
Size:  4, Capacity:  5
Size:  5, Capacity:  5
Size:  6, Capacity:  8
Size:  7, Capacity:  8
Size:  8, Capacity:  8
Size:  9, Capacity: 13
Size: 10, Capacity: 13
Size: 11, Capacity: 13
Size: 12, Capacity: 13
Size: 13, Capacity: 13
Size: 14, Capacity: 20
Size: 15, Capacity: 20
Size: 16, Capacity: 20
Size: 17, Capacity: 20
73
ответ дан 27 November 2019 в 21:28
поделиться

Нет, нельзя! Java ArrayList не предоставляет способа доступа к его текущей емкости.

Вы можете построить ArrayList только с указанием начальной емкости с помощью конструктора ArrayList(int initialCapacity) или увеличить емкость, вызвав ensureCapacity().

19
ответ дан 27 November 2019 в 21:28
поделиться

Я собираюсь нарушить тенденцию... у пользователя есть вопрос, хотя и без контекста. Без контекста знать емкость не нужно, так как резервный массив будет расти, чтобы вместить...

Вы можете сделать следующее, чтобы точно узнать, какова емкость вашего ArrayList. Побочным эффектом является то, что резервный массив будет обрезан до точного количества элементов в массиве:

ArrayList list = new ArrayList();
//add a bunch of elements
list.trimToSize();
System.out.println("Capacity = " + list.size());

Наслаждайтесь!

1
ответ дан 27 November 2019 в 21:28
поделиться

ArrayList является абстракцией для автоматически расширяемого Списка элементов. Вам редко нужно знать его емкость. Рассмотрим Effective Java 2nd Edition, Item 52: Обращайтесь к объектам по их интерфейсам. С практической точки зрения вас даже не должно волновать, является ли это ArrayList или LinkedList; это просто Список.

Тем не менее, эти методы могут вас заинтересовать:

  • ArrayList(int initialCapacity)
    • Создает пустой список с указанной начальной емкостью.
  • void secureCapacity(int minCapacity)
    • При необходимости увеличивает емкость этого экземпляра ArrayList, чтобы гарантировать, что он может содержать как минимум количество элементов, указанное аргументом минимальной емкости.
  • void trimToSize()
    • Урезает емкость этого экземпляра ArrayList до текущего размера списка. Приложение может использовать эту операцию, чтобы минимизировать объем хранилища экземпляра ArrayList.
10
ответ дан 27 November 2019 в 21:28
поделиться

Вам не нужно беспокоиться о емкости, это внутренняя деталь реализации. Если внутренний массив заполнится, то он расширится. Вы можете узнать, сколько элементов в настоящее время находится в вашем ArrayList, с помощью метода size().

1
ответ дан 27 November 2019 в 21:28
поделиться

Из спецификации: "Емкость - это размер массива, используемого для хранения элементов в списке. Он всегда не меньше размера списка. По мере добавления элементов в ArrayList, его емкость увеличивается автоматически. Подробности политики роста не уточняются, кроме того факта, что добавление элемента имеет постоянную амортизированную временную стоимость».

Таким образом, невозможно сказать, какова текущая емкость и как она растет.

1
ответ дан 27 November 2019 в 21:28
поделиться

Это нужно во время выполнения или можно получить во время тестирования? При тестировании вы обычно можете увидеть емкость с помощью вашего любимого отладчика IDE. У меня нет точного числа, но обычно 1,7 — это размер увеличения емкости. Поэтому, если вы создадите массив с 10 элементами, java сделает его размером 17.

0
ответ дан 27 November 2019 в 21:28
поделиться

API этого не предоставляет. Внутри емкость умножается на коэффициент всякий раз, когда add(..) вызывается при полной емкости. Однако спецификация Java ничего не говорит об этом постоянном коэффициенте... В реализации Sun используется коэффициент 1,5, поэтому у вас есть верхняя граница емкости 1,5*size().

Помните, что вы можете использовать функцию trimToSize(), чтобы «сжать» список и сделать его емкость равной size().

0
ответ дан 27 November 2019 в 21:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: