Java Arraylist убедиться, что емкость не работает - PullRequest
13 голосов
/ 07 октября 2011

Либо я делаю это неправильно, либо я не понимаю, как работает этот метод.

ArrayList<String> a = new ArrayList<String>();
a.ensureCapacity(200);
a.add(190,"test");
System.out.println(a.get(190).toString());

Я бы подумал, что sureCapacity позволит мне вставить запись с индексом до этого значения.Есть ли другой способ сделать это?

Я получаю ошибку IndexOutOfBounds в третьей строке.

Ответы [ 8 ]

35 голосов
/ 07 октября 2011

Нет, ensureCapacity не меняет логический размер ArrayList - он меняет емкость , то есть размер, которого может достичь список до того, как ему понадобятся следующие. скопировать значения.

Вы должны очень хорошо понимать разницу между логическим размером (то есть все значения в диапазоне [0, size) доступны, и добавление нового элемента добавит его по индексу size) и емкостью, которая больше детали реализации на самом деле - это размер резервного массива, используемого для хранения.

Вызов ensureCapacity должен только когда-либо иметь какое-либо значение с точки зрения производительности (избегая чрезмерного копирования) - это не влияет на логическую модель того, что в списке, если вы понимаете, что я имею в виду.

РЕДАКТИРОВАТЬ: Звучит так, как будто вы хотите что-то вроде ensureSize() метода, который может выглядеть примерно так:

public static void ensureSize(ArrayList<?> list, int size) {
    // Prevent excessive copying while we're adding
    list.ensureCapacity(size);
    while (list.size() < size) {
        list.add(null);
    }
}
3 голосов
/ 07 октября 2011

Так как другие упоминали, ensureCapacity не для этого. Похоже, вы хотите начать с ArrayList из 200 нулей? Тогда это будет самый простой способ сделать это:

ArrayList<String> a = new ArrayList<String>(Arrays.asList( new String[200] ));

Тогда, если вы хотите заменить элемент 190 на "test", сделайте:

a.set(190, "test");

Это отличается от

a.add(190, "test");

, который добавит «test» в индекс 190 и сместит остальные 9 элементов вверх, в результате получится список размером 201.

Если вы знаете, что у вас всегда будет 200 элементов, лучше использовать массив.

2 голосов
/ 07 октября 2011

Обеспечение способности не добавлять элементы в список. Вы можете получить элемент 190 или добавить элемент 190, только если вы уже добавили 191 элемент. «Емкость» - это просто количество объектов, которые ArrayList может удерживать до того, как ему потребуется изменить размер своей внутренней структуры данных (массива). Если ArrayList имеет getCapacity (), то делает это:

ArrayList<String> a = new ArrayList<String>();
a.ensureCapacity(200);
System.out.println(a.size());
System.out.println(a.getCapacity());

выведет 0 и некоторое число больше или равное 200 соответственно

1 голос
/ 07 октября 2011

ArrayList поддерживает свою емкость (размер внутреннего массива) отдельно от своего размера (количество добавленных элементов), а метод 'set' зависит от индекса, уже назначенного элементу. Нет способа установить размер. Если вам это нужно, вы можете добавить фиктивные элементы с помощью цикла:

for (int i = 200; --i >= 0;) a.add(null);
0 голосов
/ 07 октября 2015
  public static void fillArrayList(ArrayList<String> arrayList, long size) {
    for (int i = 0; i < size + 1; i++) {
      arrayList.add(i,"-1");
    }
  }

public static void main(String[] args) throws Exception {
  ArrayList<String> a = new ArrayList<String>(10);
  fillArrayList(a, 190);
  a.add(190,"test");
  System.out.println(a.get(190).toString());
}
0 голосов
/ 14 июня 2015

Добавление 190 пустых записей в ArrayList пахнет неправильным использованием структуры данных.

  1. Подумайте об использовании стандартного примитивного массива.

  2. Если вам требуются непатентованные средства или вы хотите более эффективно использовать пространство, подумайте, что SparseArray или даже Map, например HashMap, может подойти для ваших целей.

0 голосов
/ 07 октября 2011

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

0 голосов
/ 07 октября 2011

Еще раз JavaDoc, чтобы прояснить ситуацию:

Throws: IndexOutOfBoundsException 
    - if index is out of range (index < 0 || index > size()).

Обратите внимание, что size() возвращает количество элементов, хранящихся в настоящее время в списке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...