The copy() method of java. util. Collections class is used to copy all of the elements from one list into another. After the operation, the index of each copied element in the destination list will be identical to its index in the source list.
The clone() method of the ArrayList class is used to clone an ArrayList to another ArrayList in Java as it returns a shallow copy of its caller ArrayList. Syntax: public Object clone(); Return Value: This function returns a copy of the instance of Object.
b
has a capacity of 3, but a size of 0. The fact that ArrayList
has some sort of buffer capacity is an implementation detail - it's not part of the List
interface, so Collections.copy(List, List)
doesn't use it. It would be ugly for it to special-case ArrayList
.
As tddmonkey has indicated, using the ArrayList constructor which takes a collection is the way to in the example provided.
For more complicated scenarios (which may well include your real code), you may find the collections within Guava useful.
Calling
List<String> b = new ArrayList<String>(a);
creates a shallow copy of a
within b
. All elements will exist within b
in the exact same order that they were within a
(assuming it had an order).
Similarly, calling
// note: instantiating with a.size() gives `b` enough capacity to hold everything
List<String> b = new ArrayList<String>(a.size());
Collections.copy(b, a);
also creates a shallow copy of a
within b
. If the first parameter, b
, does not have enough capacity (not size) to contain all of a
's elements, then it will throw an IndexOutOfBoundsException
. The expectation is that no allocations will be required by Collections.copy
to work, and if any are, then it throws that exception. It's an optimization to require the copied collection to be preallocated (b
), but I generally do not think that the feature is worth it due to the required checks given the constructor-based alternatives like the one shown above that have no weird side effects.
To create a deep copy, the List
, via either mechanism, would have to have intricate knowledge of the underlying type. In the case of String
s, which are immutable in Java (and .NET for that matter), you don't even need a deep copy. In the case of MySpecialObject
, you need to know how to make a deep copy of it and that is not a generic operation.
Note: The originally accepted answer was the top result for Collections.copy
in Google, and it was flat out wrong as pointed out in the comments.
Just do:
List a = new ArrayList();
a.add("a");
a.add("b");
a.add("c");
List b = new ArrayList(a);
ArrayList has a constructor that will accept another Collection to copy the elements from
The answer by Stephen Katulka (accepted answer) is wrong (the second part).
It explains that Collections.copy(b, a);
does a deep copy, which it does not. Both, new ArrayList(a);
and Collections.copy(b, a);
only do a shallow copy. The difference is, that the constructor allocates new memory, and copy(...)
does not, which makes it suitable in cases where you can reuse arrays, as it has a performance advantage there.
The Java standard API tries to discourage the use of deep copies, as it would be bad if new coders would use this on a regular basis, which may also be one of the reason why clone()
is not public by default.
The source code for Collections.copy(...)
can be seen on line 552 at:
http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Core/Collections-Jar-Zip-Logging-regex/java/util/Collections.java.htm
If you need a deep copy, you have to iterate over the items manually, using a for loop and clone() on each object.
the simplest way to copy a List is to pass it to the constructor of the new list:
List<String> b = new ArrayList<>(a);
b
will be a shallow copy of a
Looking at the source of Collections.copy(List,List)
(I'd never seen it before) it seems to be for coping the elements index by index. using List.set(int,E)
thus element 0 will over write element 0 in the target list etc etc. Not particularly clear from the javadocs I'd have to admit.
List<String> a = new ArrayList<>(a);
a.add("foo");
b.add("bar");
List<String> b = new ArrayList<>(a); // shallow copy 'a'
// the following will all hold
assert a.get(0) == b.get(0);
assert a.get(1) == b.get(1);
assert a.equals(b);
assert a != b; // 'a' is not the same object as 'b'
List b = new ArrayList(a.size())
doesn't set the size. It sets the initial capacity (being how many elements it can fit in before it needs to resize). A simpler way of copying in this case is:
List b = new ArrayList(a);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With