views:

10392

answers:

9

I have an ArrayList<String> that I'd like to return a copy of. The ArrayList clone method has the following signature:

public Object clone()

After I call this method, how do I cast the returned Object back to a ArrayList<String>?

+2  A: 
ArrayList first = new ArrayList ();
ArrayList copy = (ArrayList) first.clone ();
jodonnell
+5  A: 
ArrayList newArrayList = (ArrayList) oldArrayList.clone();
Vinko Vrsalovic
This will work fine for Strings (which is what the question asked for), but it is worth noting that ArrayList.clone will perform a shallow copy, so if there were mutable objects in the list, they will not be cloned (and changing one in one list will change that one in the other list as well.
pkaeding
You should avoid using raw types in anything but legacy code. You're better off using `ArrayList<String> newArrayList = (ArrayList<String>) oldArrayList.clone();`.
cdmckay
+1  A: 

I find using addAll works fine.

ArrayList(String) copy = new ArrayList(String)();
copy.addAll(original);

parentheses are used rather than the generics syntax

Allain Lalonde
That'll work for Strings, but not for mutable objects. You'll want to clone those as well.
jodonnell
Yeah, his question is for strings. And he has the problem of generics which don't really like the casting stuff in this case.
Allain Lalonde
Also, ArrayList.clone will only do a shallow clone, so mutable objects in the list won't be cloned using that method either.
pkaeding
That should be ArrayList<String> btw. Also, you're probably better off using new ArrayList<String>(original) as it's less writing and just as clear.
cdmckay
+1  A: 

I think this should work:

ArrayList<String> orig = new ArrayList&<String>();
ArrayList<String> copy = (ArrayList<String>) orig.clone()
pkaeding
This won't work because List doesn't have a clone method.
Bill the Lizard
Indeed. I just updated it to fix this.
pkaeding
Well, now my comment just looks stupid. :)
Bill the Lizard
+3  A: 

I think this should do the trick using the Collections API:

Note: the copy method runs in linear time.

//assume oldList exists and has data in it.
List<String> newList = new ArrayList<String>();
Collections.copy(newList, oldList);
Kamikaze Mercenary
Why not just use new ArrayList<String>(oldList) ?
cdmckay
+8  A: 

Why would you want to clone? Creating a new list usually makes more sense.

List<String> strs;
...
List<String> newStrs = new ArrayList<String>(strs);

Job done.

Tom Hawtin - tackline
You may not know what type of List it is. It might be a LinkedList, MyOwnCustomList or a subclass of ArrayList, in which case newing an ArrayList would be the incorrect type.
Steve Kuo
Would I care which implementation the original list used? I probably care which implementation the new list uses.
Tom Hawtin - tackline
@Steve Kuo: The signature is `ArrayList(Collection<? extends E> c)` meaning it doesn't matter what kind of list you use as an argument.
cdmckay
cdmckay, the issue is about the behaviour of the new List. For ArrayList vs LinkedList, what should it's performance characteristics be. I say it should be what the copying code asks for. Steve Kuo appears to believe that it should be whatever the original list happened to be.
Tom Hawtin - tackline
+4  A: 

Be advised that Object.clone() has some major problems, and its use is discouraged in most cases. Please see Item 11, from "Effective Java" by Joshua Bloch for a complete answer. I believe you can safely use Object.clone() on primitive type arrays, but apart from that you need to be judicious about properly using and overriding clone. You are probably better off defining a copy constructor or a static factory method that explicitly clones the object according to your semantics.

Julien Chastang
A: 

just create a new one: new ArrayList<String>(origArrayList)

You didn't read all the answers, did you?
Michael Myers
A: 

Be very careful when cloning ArrayLists. Cloning in java is shallow. This means that it will only clone the Arraylist itself and not its members. So if you have an ArrayList X1 and clone it into X2 any change in X2 will also manifest in X1 and vice-versa. When you clone you will only generate a new ArrayList with pointers to the same elements in the original.

Juan Besa