0

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

2
  • 1
    ArrayList newArrayList = (ArrayList) oldArrayList.clone(); Commented 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. Commented Mar 26, 2013 at 5:23

6 Answers 6

2

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
}
Sign up to request clarification or add additional context in comments.

4 Comments

is it work? I think it will still give same reference of object in list.
@takrbuiam When in doubt, check the documentation: ArrayList API. A very important tool for any Java developer.
@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.
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.
1

You can use Clone method.

caller(ArrayList<String> a)
{
    callee((List<String>)a.clone());
}

callee(List<String> aCloned)
{

}

5 Comments

As far as I know, List doesn't have the clone() method as it does not implement Cloneable. Its ArrayList which does that.
@R.J List is an interface, therefore it doesn't have any methods. The .clone() method is defined in Object and, counterintuitively, is not related to the Cloneable interface. Check the docs
@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.
You're right List and Object are not related and .clone() can't be invoked.
@R.J, madth3: thanks for clearing the confusion and corretion made.
1

You will have to make a copy of the object before passing it to the function.

Comments

1

use the new ArrayList of the original array list in the sub method.

Comments

1

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.

2 Comments

Yes, new reference of list gave but same object reference is there.
But whatever change you make to this list does not affect the original list. Since String objects are immutable, you shouldn't have a problem I guess.
1

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

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.
@madth3 see my editable answer. it has Test Object. is it ok? it still give same reference of object. see in debug mode.
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.