#java #list #indexoutofboundsexception
#java #Список #исключение indexoutofboundsexception
Вопрос:
Согласно документам, вы можете вставлять объекты в любую позицию в списке:
Пользователь этого интерфейса имеет точный контроль над тем, где в списке вставляется каждый элемент.
(источник: http://download.oracle.com/javase/6/docs/api/java/util/List.html )
Но следующая программа завершается с ошибкой IndexOutOfBoundsException:
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
ArrayList<String> myList = new ArrayList<String>();
myList.add(0, "derp");
myList.add(2, "herp");
for (String s : myList) {
System.out.println("Le string: " s);
}
}
}
Это также не помогает явно установить начальную емкость (что имеет некоторый смысл, поскольку значение по умолчанию равно 10).
Почему я не могу вставлять объекты в любую позицию, если их индекс меньше емкости? Всегда ли размер равен количеству вставленных элементов?
Ответ №1:
Вы можете вставить объект в любую допустимую позицию. Внимательно посмотрите на Javadoc для add(int, E)
:
Выдает:
Исключение IndexOutOfBoundsException — если индекс находится вне диапазона(index < 0 || index > size())
Другими словами, вставка элемента всегда увеличивает размер списка на 1. Вы можете вставить либо в конце, либо в середине… но вы не можете вставить после конца.
Емкость an ArrayList
фактически является деталью реализации — она определяет, когда резервный массив необходимо заменить на больший, чтобы справиться с большим количеством элементов. Размер списка здесь является важной частью — список емкостью 100, но размером 5 по-прежнему является списком из 5 элементов, и поэтому вставка в позицию 67 в такой список не имеет смысла.
Комментарии:
1. @fiskeben: это не отстойно — если вам нужна произвольная карта ключ / значение, используйте
Map
вместо этого. Если вы хотите иметь упорядоченный список, вам нужно явно заполнить все элементы, а не просто случайным образом вводить их, не имея представления о реальном размере списка.
Ответ №2:
Емкость списка не совпадает с его размером.
Емкость — это свойство списков, поддерживаемых массивом (например ArrayList
, или Vector
), и это выделенный размер резервного массива (то есть максимальное количество элементов, которые вы могли бы поместить до необходимости расширения структуры).
Размер, как вы говорите, — это количество элементов, присутствующих в списке.
Тогда почему бы вам не вставить элемент везде, где вы хотите, пока для него есть место? Просто, потому List
что интерфейс не определяет, как создается резервная копия объекта, и вы не могли бы сделать это чем-то вроде LinkedList
; поэтому однородным (и правильным) поведением является выдача исключения, когда это происходит.
Итак, у вас есть два варианта:
- Правильно инициализируйте список, добавив значения по умолчанию до желаемого размера.
- Если
null
для вас это разумное значение по умолчанию, вы можете использовать массив напрямую.
Ответ №3:
myList.add(2, «herp») должен быть myList.add(1, «herp»)
При увеличении размер списка увеличивается на 1, а не на 2.
Ответ №4:
ArrayList имеет два элемента: емкость и размер
емкость — это длина базового массива, размер — это длина массива, который представляет ArrayList
итак, вам нужно добавить данные в список, чтобы сам ArrayList получил размер, в который вы хотите вставить данные
Ответ №5:
Размер списка всегда равен количеству вставленных элементов
Throws:
IndexOutOfBoundsException - if the index is out of range (index < 0 || index > size())
Ответ №6:
Сначала myList.add(0, "herp")
будет вставлено, затем будет проверен размер. Тогда размер 1
равен, но вы вставляете в позицию 2
.