I have a list of string in my code. I am passing that list of string to a function and modifying it.( I am adding/deleting few elements from the list).But i dont want these changes to get reflected in the caller function. The changes should be reflected only in the callee function. But because objects are passed by reference, I think the changes are getting reflected in both functions. How can I avoid this. Please help
-
1ArrayList newArrayList = (ArrayList) oldArrayList.clone();Code2Interface– Code2Interface2013-03-26 05:15:44 +00:00Commented Mar 26, 2013 at 5:15
-
Added extra bit: Also do take care that the objects within the list can also be changed in the callee function if the objects in the list are not immutable. List cloning will create a shallow copy and not deep copy. So if you want to protect the objects inside the list 1) do deep cloning 2) make object immutable.Narendra Pathai– Narendra Pathai2013-03-26 05:23:13 +00:00Commented Mar 26, 2013 at 5:23
Add a comment
|
6 Answers
Inside the method, you can explicitly make a copy of the list:
private void method(ArrayList<String> list) {
ArrayList<String> copy = new ArrayList<String>(list);
// Rest of the method
}
4 Comments
bNd
is it work? I think it will still give same reference of object in list.
madth3
@takrbuiam When in doubt, check the documentation: ArrayList API. A very important tool for any Java developer.
bNd
@madth3 Yes I know it. I already tried this method. I am sure that it does not make copy of object. it will give same reference of object.
madth3
It will create a new list with the same objects. As I commented in your answer, when the objects are immutable it doesn't matter.
You can use Clone method.
caller(ArrayList<String> a)
{
callee((List<String>)a.clone());
}
callee(List<String> aCloned)
{
}
5 Comments
Rahul
As far as I know,
List doesn't have the clone() method as it does not implement Cloneable. Its ArrayList which does that.Rahul
@madth3 - Thank you for correcting me. But my edit still stands correct, as you still can't call
clone() method on List<String> a but can call on ArrayList<String> a.madth3
You're right
List and Object are not related and .clone() can't be invoked.Azodious
@R.J, madth3: thanks for clearing the confusion and corretion made.
Typically the clone method is not recommended. See this clone(): ArrayList.clone() I thought does a shallow copy
However you can try this method
public void doOperation(List<String> list){
List<String> duplicateList = new ArrayList(list);
// add, or delete stuff on duplicateList
}
Here, you use the constructor of the ArrayList to give you a new copy of the list that is passed in.
You have to create new list from old list manually using looping and need to pass to that method. i.e.
List<String> list=new ArrayList<>();
list.add("first");
list.add("last");
List<String>list2 =new ArrayList<String>();
for(String value:list)
{
list2.add(new String(value));
}
System.out.println("list2-->"+list2);
Because new ArrayList<String>(list); is give a new reference of list but the object still have a same reference.
Edit:
public class ArrayCopy {
public static void main(String[] args) {
ArrayCopy arrayCopy=new ArrayCopy();
arrayCopy.copyData();
}
public void copyData()
{
List<Test> oldList=new ArrayList<Test>();
oldList.add(new Test("1",10));
oldList.add(new Test("2",45));
List<Test> newList =new ArrayList<Test>(oldList);
System.out.println("newList-->"+newList);
/**
* New Copy of Data
*/
List<Test> newList1 =new ArrayList<Test>();
for(Test test:newList)
{
newList1.add(copyProperty(test));
}
System.out.println("newList-->"+newList1);
}
private Test copyProperty(Test test)
{
Test newTest=new Test(test.getId(), test.getNumber());
return newTest;
}
class Test{
String id;
int number;
public Test(String id,int number) {
this.id=id;
this.number=number;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
}
3 Comments
madth3
If the objects in
list could change then you would be right, but as Strings are inmutable, creating copies is useless. Given solutions using the ArrayList constructor are fine. Cloneable is not related to the .clone() method.bNd
@madth3 see my editable answer. it has Test Object. is it ok? it still give same reference of object. see in debug mode.
madth3
I've always agreed that the elements in both lists are the same. I'd recommend reading on immutable objects to understand why in some cases it doesn't matter.