Почему этот код выдает исключение IndexOfOutBoundsException — то есть, что случилось с обеспечения Capacity()?
Вопрос
Рассмотрим следующие два фрагмента кода:
int index = 676;
List<String> strings = new ArrayList<String>();
strings.add(index, "foo");
и
int index = 676;
List<String> strings = new ArrayList<String>();
strings.ensureCapacity(index);
strings.add(index, "foo");
В первом случае я не удивлен, увидев исключение IndexOfOutBoundsException. По данным API, add(int index, E element)
выдаст исключение IndexOfOutBoundsException, «если индекс выходит за пределы диапазона (index < 0 || index > size())
".Размер strings
равен 0 до добавления каких-либо элементов, поэтому индекс определенно будет больше размера ArrayList.
Однако во втором случае я ожидаю, что вызов ensureCapacity
расти strings
такой, что вызов add
правильно вставит строку "foo"
по индексу 676 - но это не так.
Почему нет?
Что мне делать, чтобы
add(index, "foo")
работает наindex > strings.size()
?
Решение
Емкость базового массива в ArrayList отличается от методов List API более высокого уровня (добавление, удаление и т. д.) и зависит только от размера резервного массива.Если вы хотите разрешить добавление элементов за пределы списка, вам нужно будет закодировать это самостоятельно (или найти коллекцию, которая сделает это за вас) в служебном классе, заполняя значениями NULL, пустыми объектами или чем-то еще, что ваше приложение ожидает между новыми индекс и старый размер.
Другие советы
ArrayList.ensureCapacity() не меняет фактический размер списка (который возвращается функцией size()), а скорее перераспределяет внутренний буфер так, что ему не нужно будет перераспределять буфер для увеличения до этого размера (при вызове list .add(объект).
/**
* Increases the capacity of this <tt>ArrayList</tt> instance, if
* necessary, to ensure that it can hold at least the number of elements
* specified by the minimum capacity argument.
*/
Если предположить, что вы ищете
Integer index = Integer.valueOf(676);
Map<Integer,String> strings = new HashMap<Integer,String>();
strings.put(index, "foo");
ваша длина равна 676, но вы должны помнить, что они отсчитываются от нуля, поэтому на самом деле вам нужно, чтобы индекс -1 был вашим максимальным числом.