Установить метод ArrayList, бросающий IndexOutOfBoundsException
Во время работы над ArrayList
, я обнаружил, что после установки начального размера массива с помощью конструктора с initialCapacity
, тогда использование set()
будет генерировать исключение, хотя массив создан, но размер не установлен правильно.
Использование ensureCapacity()
не будет работать, потому что оно основано на массиве elementData
вместо size
.
Существуют и другие побочные эффекты из-за статического DEFAULT_CAPACITY
с ensureCapacity()
.
Единственный способ сделать эту работу - использовать add() столько раз, сколько требуется после использования конструктора.
Пожалуйста, проверьте код ниже.
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List test = new ArrayList(10);
test.set(5, "test");
System.out.println(test.size());
}
Я не уверен, почему java выбрасывает это исключение.
Поведение, которое я ожидал: test.size()
должен возвращать 10, и установить (5,...) должно работать.
АКТУАЛЬНО: выбрасывает исключение IndexOutOfBoundsException
.
Так возникает метод set, вызывающий проблему?
Ответы
Ответ 1
test.set(5, "test");
- это оператор, который генерирует это исключение, поскольку ваш ArrayList
пуст (size()
возвращает 0
, если вы попали в этот оператор), и вы не можете установить i-й элемент, если он еще не содержит значения. Вы должны добавить не менее 6 элементов в ArrayList
, чтобы test.set(5, "test");
был действительным.
new ArrayList(10)
не создает ArrayList
, размер которого равен 10. Он создает пустую ArrayList
, начальная емкость которой равна 10.
Ответ 2
Исключение не выбрано test.size()
, а test.set(5, "test");
. Это связано с тем, что вы устанавливаете элемент в индексе 5, но список в настоящее время пуст.
List test = new ArrayList(10);
не создает список, инициализированный 10 элементами null
. Он создает список с начальной емкостью 10 элементов, то есть массив поддержки имеет размер 10, но сам список по-прежнему пуст.
Если вы хотите инициализировать список с помощью 10 null
элементов, вы можете использовать
List<String> list = new ArrayList<>(Collections.nCopies(10, null));
В качестве примечания вы никогда не должны использовать необработанные типы, например List
, но всегда предпочитаете параметризованный список.
Ответ 3
Мое понимание после прохождения Документов.
Начальная емкость - это длина массива, используемая для хранения элементов списка. Это можно использовать для управления памятью и изменения размера.
Первоначальная емкость не контролирует фактический размер списка (#elements в списке), а также значения по умолчанию для элементов. Размер ArrayList после создания с начальной мощностью всегда будет равен нулю.
Ответ 4
List test = new ArrayList(10);
создает пустой список, который имеет емкость 10 элементов. Он не содержит элемент на шестом месте, поэтому вы не сможете установить элемент в этой позиции.
Ответ 5
List test = new ArrayList(10);
создает пустой ArrayList
исходных типов (Object
) с начальной мощностью (емкость списка изначально инициализирует внутренний массив длиной 10), чтобы не путать с размером (число списка элементов).
Чтобы понять больше, обратите внимание, что ArrayList
- это не что иное, как манипуляция массивом, чтобы динамически изменять размер массива, который мы не могли сделать непосредственно с массивом. В конечном счете, это массив умный.
Установив начальную емкость, мы сообщаем ArrayList
сначала создать размер массива 10
(по умолчанию начальная емкость - 10
).
Это то, что делает конструктор,
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];//creates initial array
}
Вы можете увеличить или уменьшить его соответственно, скажем, что вы уверены, что вам понадобится список с элементами 20
, при запуске будет лучше установить начальную емкость. Это позволяет избежать изменения размера массива, если вы уверены в минимальном количестве элементов, которые вы обязательно найдете в списке.
test.set(5, "test");
метод заменяет элемент в определенной позиции здесь, он заменит элемент в индексе 5
на test
. Но наш список пуст, у него нет элемента.
Документация этого метода говорит,
IndexOutOfBoundsException
- если index
находится за пределами допустимого диапазона (index < 0
|| index >= size()
)
Обратите внимание, что размер списка 0
, поэтому index (5
) больше размера (0
).
Ответ 6
Заменяет элемент в указанной позиции в этом списке указанным элементом.
set
Параметры
индекс
int: индекс элемента для замены
элемент
E: элемент, который должен храниться в указанной позиции
Возвраты
Е
элемент ранее в указанной позиции
Выдает
IndexOutOfBoundsException