2013-11-09 5 views
3

Почему следующее возвращает исключение IndexOutOfBoundsException? (Индекс 5, размер 0)Ошибка Java вне диапазона

gridList = new ArrayList<Integer>(9); 
gridList.add(5, 2); 

Я был под впечатлением, что вызов конструктора инициализирует мой ArrayList к размеру.

Я совершенно новый с java, поэтому извиняюсь.

+0

Количество, которое вы даете, это * емкость *, а не размер. Емкость - это количество элементов, которые вы можете добавить, без изменения базовой структуры данных, т. Е. Сколько вы ожидаете от List, а не того, что у нее есть. –

ответ

2

Это все еще пустой список (размер 1, только индекс доступен 0). Просто емкость равна 9. Как только емкость достигнет емкости, ArrayList будет расширяться.

Примечание: размер и емкость две разные вещи.

+0

Любой совет для быстрого/эффективного способа инициализации arraylist для этой емкости с 0 значениями? – Secret

+0

Если вы имеете в виду инициализацию с размером больше 0, вы не можете, если вы не инициализируете его, будет другой список, но тогда он не будет пустым. Вы должны добавить значения до того, как размер увеличится. Если вы хотите использовать индексы, попробуйте использовать массив вместо arraylist. Затем, если вы хотите использовать его как ArrayList, вы можете использовать 'Arrays.asList (yourArray)' –

+0

Если у вас уже установлен размер (9), массив будет эффективным –

4

ArrayList является initialized with a capacity из 9, но список не заполнен. Таким образом, вы не можете добавить элемент в позицию 5, поскольку эта позиция не существует в списке.

3

Пожалуйста, следуйте исходному коду ArrayList, вы можете видеть, что размер и емкость различной концепции. checkBoundInclusive() способ сравнение indexsize не capacity.

public ArrayList(int capacity) 
    { 
    // Must explicitly check, to get correct exception. 
    if (capacity < 0) 
     throw new IllegalArgumentException(); 
    data = (E[]) new Object[capacity]; 
    } 


    public void add(int index, E e) 
    { 
     checkBoundInclusive(index); 
     modCount++; 
     if (size == data.length) 
     ensureCapacity(size + 1); 
    if (index != size) 
     System.arraycopy(data, index, data, index + 1, size - index); 
     data[index] = e; 
     size++; 
    } 


    private void checkBoundInclusive(int index) 
    { 
     // Implementation note: we do not check for negative ranges here, since 
     // use of a negative index will cause an ArrayIndexOutOfBoundsException, 
     // a subclass of the required exception, with no effort on our part. 
     if (index > size) 
     throw new IndexOutOfBoundsException("Index: " + index + ", Size: " 
              + size); 
    } 
6

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

ArrayList<Integer> gridList = new ArrayList<Integer>(9); 
System.out.println(gridList); 

Output: [] 

Если вы хотите инициализировать ArrayList с 9 Целые (например, девять нулей), попробуйте это «convenience implementation»:

ArrayList<Integer> gridList = new ArrayList<Integer>(Collections.nCopies(9, 0)); 
System.out.println(gridList); 

Output: [0, 0, 0, 0, 0, 0, 0, 0, 0] 

Как вы можете видеть, это заполняет ArrayList значениями во время инициализации, поэтому вы можете теперь звонить gridList.add(5, 2); без IndexOutOfBoundsException.

1

Как уже отмечался в тыс случае, если вы вступаете ан alement в положении 5, но у вас нет ничего там и нет никаких элементов, прежде - смотрите здесь:

ArrayList<Integer> g = new ArrayList<Integer>(9); 
    g.add(0, 10); 
    g.add(1, 20); 
    g.add(2, 30); 
    g.add(3, 40); 

    for(Integer v: g) System.out.print(v + " "); 
    System.out.println(); 

    g.add(2,99); 

    for(Integer v: g) System.out.print(v + " "); 
    System.out.println(); 

    g.add(88); // use this to just push value at the end 

    for(Integer v: g) System.out.print(v + " "); 
    System.out.println(); 

выходов:

10 20 30 40 
10 20 99 30 40 
10 20 99 30 40 88 
Смежные вопросы