2012-01-04 4 views
6

Почему в этом примере создается java.lang.IndexOutOfBoundsException, если размер ArrayList предопределен? Как решить эту проблему?Индекс 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); 

ответ

11

Вы не можете поместить элемент в 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); 

редактировать/Заменено добавить набором для замены нулевого объекта

+3

Чтобы быть более ясным, что это на самом деле, что вы не можете вставить элемент в индекс, который еще не существует. –

+3

Не следует угадывать мудрость здесь, но не делает 3-й add() в вышеупомянутом решении * shift * содержимым, так что значение1 теперь находится в индексе 2, а не 1? Док в add() с индексом указывает на это. Я считаю, что содержимое массива после этого будет {value2, null, value1}. – rfeak

2

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

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

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

Чтобы получить заказ вы кажетесь хотите здесь.

+0

Это не сработает для моего случая, потому что мне может понадобиться добавить определенный элемент в позицию 5, следующий в позиции 2, следующий в позиции 7 и т. Д. –

+1

@KlausosKlausos - Звучит так, будто вы действительно не хотите ArrayList, по крайней мере, не изначально. Возможно, лучше начать с простого массива определенного размера, сделать все ваши вставки по индексу, чтобы вам не приходилось играть в смешные игры с помощью ArrayList, THEN помещало Array в ArrayList. Кроме того, имейте в виду, что add() в индексе вызывает сдвиг в существующем содержимом массива. Добавляя в положение 5, позиция 2 меняет то, что вы вставили на 5, теперь должно быть на 6. – rfeak

8

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

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

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

0

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

nums.add(0, value1); 
nums.add(0, value2); 
2

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

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

1

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

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

Вы не определяя размер из НУМСА, вы определяющая начальной емкости - в этом смысле, ArrayLists Арена» t как встроенные массивы (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

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

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)); 
Смежные вопросы