Ява.ленг.IndexOutOfBoundsException: источник не вписывается в dest


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

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)

почему?

3 57

3 ответа:

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

ключевая часть от Collections.copy документации:

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

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

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

ArrayList <Integer> numbersCopy = new ArrayList<Integer>(numbers);

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

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