Вставить в любую позицию в java.util.List

#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())
 

Javadoc

Ответ №6:

Сначала myList.add(0, "herp") будет вставлено, затем будет проверен размер. Тогда размер 1 равен, но вы вставляете в позицию 2 .