Индекс ArrayList вне границ - PullRequest
11 голосов
/ 04 января 2012

Почему java.lang.IndexOutOfBoundsException повышается в этом примере, если размер ArrayList был предопределен? Как решить эту проблему?

int size = 2:
ArrayList<Integer[]> nums = new ArrayList<Integer[]>(size);
Integer[] value1 = {1,2,3};
Integer[] value2 = {1,2};
nums.add(1,value1); // java.lang.IndexOutOfBoundsException
nums.add(0,value2);

Ответы [ 7 ]

15 голосов
/ 04 января 2012

Вы не можете поместить элемент в ArrayList до того, как будет установлен другой. Если вы хотите сделать это, вам сначала нужно будет присвоить нулевые значения элементу на месте 0.

Это будет работать, если вы сделаете:

int size = 2:
ArrayList<Integer[]> nums = new ArrayList<Integer[]>(size);
Integer[] value1 = {1,2,3};
Integer[] value2 = {1,2};
nums.add(0, null);
nums.add(1,value1);
nums.set(0,value2);

edit / Replaceced add by set для замены нулевого объекта

9 голосов
/ 04 января 2012

Аргумент к конструктору ArrayList не является размером списка, как предполагает ваш код;это емкость базового хранилища, используемого структурой данных.

Емкость будет увеличиваться по мере необходимости при добавлении элементов в список.Единственная причина указать начальную емкость в конструкторе - это предварительно выделить большую емкость, если вы знаете, что собираетесь добавлять много элементов.Это означает, что базовый массив не требует слишком частого изменения размера при добавлении.

Независимо от того, какое значение вы указываете в конструкторе ArrayList, размер спискарегулируется исключительно тем, что вы положили в него, поэтому вы не можете получить элемент с index из 1, пока не добавите хотя бы 2 элемента.

3 голосов
/ 04 января 2012

http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#ArrayList(int)

То, что вы указываете, это начальная емкость, это просто начальный размер, который имеет внутренний массив и который автоматически увеличивается при необходимости. Это не имеет ничего общего с позицией элемента , следовательно, ваша ошибка. Кстати, емкость ArrayLists по умолчанию равна 10, поэтому вы фактически делаете ее меньше, чем по умолчанию.

3 голосов
/ 04 января 2012

В то время, когда вы add() к ArrayList, длина списка равна 0. Вы не можете добавить после текущего конца List.

Я бы предложил сделать:

nums.add(value2);
nums.add(value1); 

Чтобы получить заказ, который вам нужен здесь.

1 голос
/ 04 января 2012

Согласно javadoc , когда вы пишете

ArrayList<Integer[]> nums = new ArrayList<Integer[]>(size);

Вы не определяете размер из чисел , вы 'повторное определение начальной емкости - в этом смысле ArrayLists не похожи на встроенные массивы ( value1 и value2 в вашем коде).

Вы можете попробовать это сами: выведите размер nums после каждой строки (код очищен для исключения IndexOutOfBoundsException.

int size = 2:
ArrayList<Integer[]> nums = new ArrayList<Integer[]>(size);
Integer[] value1 = {1,2,3};
Integer[] value2 = {1,2};
System.out.println(nums.size());
nums.add(value2);
System.out.println(nums.size());
nums.add(value1);
System.out.println(nums.size());

При этом будет напечатано:

0
1
2
0 голосов
/ 23 апреля 2015

Чтобы получить ожидаемые результаты, я бы рекомендовал использовать массивы базового типа, такие как

Integer[][] nums = new Integer[size][];

, а затем

Integer[] value1 = {1,2,3};
Integer[] value2 = {1,2};
nums[1] = value1; 
nums[0] = value2;

Если вам все еще нужен ArrayList, просто используйте

new ArrayList<Integer[]>(Arrays.asList(nums));
0 голосов
/ 04 января 2012

Чтобы получить желаемый результат, вы должны написать

nums.add(0, value1);
nums.add(0, value2);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...