#java #arraylist
#java #arraylist
Вопрос:
Либо я делаю это неправильно, либо я не понимаю, как работает этот метод.
ArrayList<String> a = new ArrayList<String>();
a.ensureCapacity(200);
a.add(190,"test");
System.out.println(a.get(190).toString());
Я бы подумал, что ensureCapacity позволит мне вставить запись с индексом до этого значения. Есть ли другой способ сделать это?
Я получаю ошибку IndexOutOfBounds в третьей строке.
Ответ №1:
Нет, ensureCapacity
не изменяет логический размер an 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);
}
}
Комментарии:
1. Итак, это то, о чем я думал, основываясь на результатах, которые я видел… Но есть ли способ сделать то, что мне нужно сделать?
2. используйте массив, если вы действительно хотите иметь один элемент в позиции 190
3. Может быть, использовать другой класс, а не ArrayList?
4. Это правильно, ребята: Я исправил опечатку. Это, несомненно, вершина моей карьеры.
5. Мой парад закончился. Спасибо, Джон. Теперь мне нужно будет придумать, как рассказать своим детям 😉
Ответ №2:
Так что, как упоминали другие 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 элементов, возможно, было бы лучше просто использовать массив.
Комментарии:
1. 1, но я просто вывел простой пример, который вызвал ту же ошибку по той же причине, что и в моей реальной ситуации. Спасибо.
Ответ №3:
Обеспечение емкости не добавляет элементы в список. Вы можете получить элемент 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, соответственно
Ответ №4:
ArrayList поддерживает свою емкость (размер внутреннего массива) отдельно от его размера (количества добавленных элементов), а метод ‘set’ зависит от индекса, уже присвоенного элементу. Нет способа установить размер. Если вам это нужно, вы можете добавить фиктивные элементы с помощью цикла:
for (int i = 200; --i >= 0;) a.add(null);
Ответ №5:
Еще раз JavaDoc, чтобы прояснить ситуацию:
Throws: IndexOutOfBoundsException
- if index is out of range (index < 0 || index > size()).
Обратите внимание, что size()
возвращает количество элементов, которые в данный момент хранятся в списке.
Ответ №6:
ensureCapacity
просто убедитесь, что емкость базового массива больше или равна аргументу. Это не изменяет размер ArrayList
. Он не вносит никаких изменений, видимых через API, поэтому вы не заметите разницы, за исключением того, что, вероятно, пройдет больше времени, прежде ArrayList
чем он изменит размер своего внутреннего массива.
Ответ №7:
Добавление 190 нулевых записей в ArrayList пахнет неправильным использованием структуры данных.
-
Подумайте об использовании стандартного примитивного массива.
-
Если вам требуется дженерики или вы хотите более эффективно использовать пространство, тогда подумайте
SparseArray
, или дажеMap
подобный aHashMap
может подойти для ваших целей.
Ответ №8:
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());
}