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

Manasvi Karanam
  • 27
  • 3
  • 10
  • 1
    ArrayList newArrayList = (ArrayList) oldArrayList.clone(); – Code2Interface Mar 26 '13 at 05: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 Mar 26 '13 at 05:23

6 Answers6

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
}
Jimmy Lee
  • 1,001
  • 5
  • 12
  • is it work? I think it will still give same reference of object in list. – bNd Mar 26 '13 at 05:24
  • 1
    @takrbuiam When in doubt, check the documentation: [ArrayList API](http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html). A very important tool for any Java developer. – madth3 Mar 26 '13 at 05:32
  • @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. – bNd Mar 26 '13 at 05:54
  • 1
    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. – madth3 Mar 26 '13 at 06:00
1

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

eliot
  • 1,319
  • 1
  • 14
  • 33
1

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

MGPJ
  • 1,062
  • 1
  • 8
  • 15
1

You can use Clone method.

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

callee(List<String> aCloned)
{

}
madth3
  • 7,275
  • 12
  • 50
  • 74
Azodious
  • 13,752
  • 1
  • 36
  • 71
  • As far as I know, `List` doesn't have the `clone()` method as it does not implement `Cloneable`. Its `ArrayList` which does that. – Rahul Mar 26 '13 at 05:23
  • @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](http://docs.oracle.com/javase/7/docs/api/java/lang/Cloneable.html) – madth3 Mar 26 '13 at 05:28
  • @madth3 - Thank you for correcting me. But my edit still stands correct, as you still can't call `clone()` method on `List a` but can call on `ArrayList a`. – Rahul Mar 26 '13 at 05:33
  • You're right `List` and `Object` are not related and `.clone()` can't be invoked. – madth3 Mar 26 '13 at 05:46
  • @R.J, madth3: thanks for clearing the confusion and corretion made. – Azodious Mar 26 '13 at 05:52
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.

Community
  • 1
  • 1
midhunhk
  • 5,560
  • 7
  • 52
  • 83
  • Yes, new reference of list gave but same object reference is there. – bNd Mar 26 '13 at 05:27
  • 1
    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. – midhunhk Mar 26 '13 at 05:31
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;
        }
    }
}
bNd
  • 7,512
  • 7
  • 39
  • 72
  • If the objects in `list` could change then you would be right, but as `String`s are inmutable, creating copies is useless. Given solutions using the `ArrayList` constructor are fine. `Cloneable` is not related to the `.clone()` method. – madth3 Mar 26 '13 at 05:47
  • @madth3 see my editable answer. it has Test Object. is it ok? it still give same reference of object. see in debug mode. – bNd Mar 26 '13 at 06:02
  • I've always agreed that the elements in both lists are the same. I'd recommend reading on [immutable objects](http://www.javapractices.com/topic/TopicAction.do?Id=29) to understand why in some cases it doesn't matter. – madth3 Mar 26 '13 at 06:16