Установить метод 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