java.lang.IndexOutOfBoundsException: Source does not fit in dest
JavaArraylistCollectionsIndexoutofboundsexceptionJava Problem Overview
On the following code:
static void findSubsets (ArrayList<Integer> numbers, int amount, int index)
{
ArrayList <Integer> numbersCopy = new ArrayList<Integer>(numbers.size());
Collections.copy(numbersCopy, numbers);
}
I'm getting the error:
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)
Why?
Java Solutions
Solution 1 - Java
Capacity does not equal size. The size parameter that you are passing in simply allocates enough memory for the size. It does not actually define elements. It's actually kind of a silly requirement of Collections.copy
, but it is one nonetheless.
The key part from the Collections.copy
JavaDocs:
> The destination list must be at least as long as the source list. If it is longer, the remaining elements in the destination list are unaffected.
You should just pass the List
to the ArrayList
's constructor to copy all of the List
to avoid the issue altogether.
Solution 2 - Java
That's a very good question and it almost certainly has to do with the fact that setting a collections capacity does not necessarily allocate the underlying objects, but why are you doing it that way when you can just:
ArrayList <Integer> numbersCopy = new ArrayList<Integer>(numbers);
Solution 3 - Java
The constructor ArrayList(Collection<? extends E> c)
will copy every elements from c
into the newly created instance, thus copying numbers
into numbersCopy
. It is the same as numbersCopy.addAll(numbers)
also, which is really what you need.
It does make sense that Collection.copy
requires the dest
array to be large enough to hold all elements from the source
array. A similar analogy is the C function memcpy
and the like.
Solution 4 - Java
While creating an ArrayList
to copy another ArrayList
using Collections.copy()
method, we need to make sure that the destination List
contains same number of values (not just same size) as source List
. For example, if source ArrayList
has values [Red,Blue,Green], then the destination ArrayList
should also contain same number of elements like [Orange,Yellow,Blue].If we create an ArrayList
with same size that of source ArrayList
, it will give OutOfBounds
exception.
Solution 5 - Java
You can also use, Collections.addAll
like Assume we need to copy List1 to List2, then
List2.addAll(List1);
Here the files will be added, if you want it more efficient then make sure you clear the list2 before adding the items of list1, like this,
list2.clear();
Solution 6 - Java
In java 8 +
List<Integer> numbersCopy = numbers.stream().collect(Collectors.toList());
It easier in java 10+
List<Integer> numbersCopy = List.copyOf(numbers);
List.copyOf()
returns an unmodifiable
List containing the elements of the given Collection.