Reputation: 10249
I'm using the following code:
List<Object> dest = new LinkedList<Object>();
Collections.copy(oldList, src);
When i execute the code, I get an exception:
java.lang.IndexOutOfBoundsException: Source does not fit in dest
at java.util.Collections.copy(Collections.java:589)
I know how to fix that, but what i don't understand is:
When i add elements manually, the list would increase the capacity automaticly. Why can't Collections#copy do that?
Upvotes: 5
Views: 4454
Reputation: 213311
Collections#copy()
is a utility method, that is intended to work for any List
. This method is intended to just re-use the existing array and not allocate any memory. So, this might be efficient, else you might anyway use the ArrayList(Collection)
constructor, which would do the expansion job for you. The fact that the size constraint, and expansion is only related to ArrayList
can also be a reason, not to add this behaviour to the method. That would just be extra code for the sake of just a particular List
implementation. That is not how programming to interface works.
And since it is clearly mentioned in the docs, they would expect you to follow it.
Upvotes: 3
Reputation: 17622
If you see the implementation of Collection.copy
method, it maintains the identical indices in source and destination Lists, after the copy operation.
To set an element at an index, set(int)
method should be used. set(int)
method expects that the index is present in the destination list (unlike add(Object)
which expands the list if there is no capacity).
Imagine if this method had used add(Object)
while copying and the dest
list had already had some elements, then the new elements (from src
) would have got added at the end of dest
list, breaking the copy contract (which means same elements @ respective same indices)
Hence the method throws exception if the destination list is not as long as source list
Upvotes: 1
Reputation: 18163
You assume, a List
size is mutable and Collections.copy()
does not assume this to theoretically broaden the purpose of this class to all classes implementing the List
interface instead of the mutable ones only.
Upvotes: -1
Reputation: 54659
As StinePike already said in https://stackoverflow.com/a/21986805 : That's how it is implemented. It is just a convenience method that you can use instead of a for-loop like
for (int i=0; i<src.size(); i++)
{
dst.set(i, src.get(i));
}
Regarding your question about the automatic size increase: It sounds as if you are actually looking for something like Collection#addAll(Collection)
- so in this case
dest.addAll(src);
Upvotes: 4
Reputation: 54692
Because this is how it is implemented. If you see the source code of this method you will see that
if (srcSize > dest.size())
throw new IndexOutOfBoundsException("Source does not fit in dest");
So if you want to implement autoincrement, Then write your own method.
Upvotes: 3