java.lang.IndexOutOfBoundsException: источник не помещается в dest - PullRequest
63 голосов
/ 27 мая 2011

На следующий код:

static void findSubsets (ArrayList<Integer> numbers, int amount, int index)
{
    ArrayList <Integer> numbersCopy = new ArrayList<Integer>(numbers.size());
    Collections.copy(numbersCopy, numbers);
}

Я получаю ошибку:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Source does not fit in dest
        at java.util.Collections.copy(Collections.java:548)
        at backtracking2.Main.findSubsets(Main.java:61)

Почему?

Ответы [ 4 ]

78 голосов
/ 27 мая 2011

Емкость не равна размеру. Параметр размера, который вы передаете, просто выделяет достаточно памяти для размера. Это на самом деле не определяет элементы. На самом деле это глупое требование Collections.copy, но, тем не менее, оно одно.

Ключевая часть из Collections.copy JavaDocs :

Список адресатов должен быть не меньше длины списка источников. Если он длиннее, остальные элементы в списке адресатов остаются без изменений.

Вы должны просто передать List в конструктор ArrayList, чтобы скопировать все List, чтобы вообще избежать этой проблемы.

18 голосов
/ 27 мая 2011

Это очень хороший вопрос, и он почти наверняка связан с тем фактом, что установка емкости коллекций не обязательно выделяет базовые объекты, но почему вы делаете это так, когда вы можете просто:

ArrayList <Integer> numbersCopy = new ArrayList<Integer>(numbers);
4 голосов
/ 27 мая 2011

Конструктор ArrayList(Collection<? extends E> c) копирует все элементы из c во вновь созданный экземпляр, таким образом копируя numbers в numbersCopy. Это то же самое, что и numbersCopy.addAll(numbers), что действительно нужно.

Имеет смысл, что Collection.copy требует, чтобы массив dest был достаточно большим, чтобы вместить все элементы из массива source. Аналогичной аналогией является функция C memcpy и т. П.

1 голос
/ 11 марта 2019

При создании ArrayList для копирования другого ArrayList с использованием метода Collections.copy() нам необходимо убедиться, что в пункте назначения List содержится то же количество значений (а не только того же размера), что и в источнике List.Например, если источник ArrayList имеет значения [Red, Blue, Green], тогда пункт назначения ArrayList также должен содержать такое же количество элементов, как [Orange, Yellow, Blue]. Если мы создаем ArrayList с таким же размеромчто из источника ArrayList, это выдаст OutOfBounds исключение.

...