Reputation: 21982
Simply put, I have a method with an ArrayList parameter. In the method I modify the contents of the ArrayList for purposes relevant only to what is returned by the method. Therefore, I do not want the ArrayList which is being passed as the parameter to be affected at all (i.e. not passed as a reference).
Everything I have tried has failed to achieve the desired effect. What do I need to do so that I can make use of a copy of the ArrayList within the method only, but not have it change the actual variable?
Upvotes: 42
Views: 68295
Reputation: 51
On the lines of the existing answers but using the ArrayList API. You can use subList(fromIndex, toIndex)
method. It explicitly creates a view of the list with only desired elements (of course, in sequence). Here, even if you modify the view with add/remove etc operations, it won't change the original list. It saves you from explicitly creating a copy.
Something like this:
public void recursiveMethod(List<Integer> list) {
if(base)
return;
recursiveCall(list);
// following will just create a tail list but will not actually modify the list
recursiveCall(list.subList(1, list.size());
}
Upvotes: 0
Reputation: 21858
Even if you had a way to pass the array list as a copy and not by reference it would have been only a shallow copy.
I would do something like:
void foo(final ArrayList list) {
ArrayList listCopy = new ArrayList(list);
// Rest of the code
}
And just work on the copied list.
Upvotes: 56
Reputation: 165
I'm not sure on why, even after new ArrayList<MyObj>(old)
the object was still changing reference in places it wasn't supposed to. So I had to instantiate a new copy of the objects inside.
I made a copy constructor like the one on the ArrayList and did like
newArray = new ArrayList<MyObj>();
for (int i = 0; i < oldArray.size(); i++) {
newArray.add(new MyObj(ondArray.get(i)));
}
Just hope to help someone else if the answer from Avi is not enough in your case, like mine with a code too messy to even understand =P
Upvotes: 3
Reputation: 7804
Try this in you method :
void method(List<Integer> list) {
List copyList = new ArrayList<Integer>();
copyList.addAll(list); // This will create a copy of all the emlements of your original list
}
Upvotes: 3
Reputation: 1399
You can create a copy of the ArrayList using ArrayList's copy constructor:
ArrayList copy = new ArrayList(original);
But if the elements of the list are also objects, then you must be aware that modifying a member of the copy will also modify that member in the original.
Upvotes: 22
Reputation: 11950
Just clone it.
public ArrayList cloneArrayList(ArrayList lst){
ArrayList list = new ArrayList();
for (int i=0; i<lst.size(); i++){
list.add(lst.get(i));
}
return list;
}
Add suggested in the comments, you can also use
ArrayList copy = new ArrayList(original);
and also
ArrayList copy = new ArrayList();
copy.addAll(original);
Upvotes: 1
Reputation: 85779
You could pass Collections#unmodifiableList(yourList)
in order to send an unmodifiable copy of your list. By the way, your List<Whatever>
is passed by value since Java always pass by value, note that in foo(List<Whatever> list)
method you can not modify the list
value but you can modify its contents.
public class MyClass {
List<Whatever> list = new ArrayList<Whatever>();
public void bar() {
//filling list...
foo(Collections.unmodifiableList(list));
}
public void foo(List<Whatever> list) {
//do what you want with list except modifying it...
}
}
Upvotes: 6
Reputation: 37381
You could use the .clone
method or a CopyOnWriteArrayList
to make a copy, thereby not impacting the original.
Upvotes: 3