简体   繁体   中英

How to create a copy of ArrayList<ArrayList<Arc>> to another ArrayList<ArrayList<Arc>>

I have a Class

public class Arc{
...
}

and 2 ArrayList

ArrayList<ArrayList<Arc>> rotalar1 = new ArrayList<ArrayList<Arc>>();
ArrayList<ArrayList<Arc>> rotalar2 = new ArrayList<ArrayList<Arc>>();

i try to copy rotalar1 to in rotalar2:

rotalar2.addAll(rotalar1);

but i have a problem. if i make any change in rotalar2 , it has an impact on rotalar1 too. I dont want to make a change in rotalar1 :

These rows make problem

rotalar2.get(random1).remove(random3);
rotalar2.get(random2).remove(random4);

Thanks for your time

Method addAll does shallow copy which means it copies all the reference of object (not actual Object) from rotalar1 to rotalar2 .

  • One way, you need to iterate over each object( Arc ) and clone it and add it to new list.
  • One other way is deep copy using serialization. Example Code

Iterate over rotalar1 an copy each list of this list to rotalar2. You can make the copy in different ways. In the first example i use the constructor and create a new list with the same elements. Be careful, if you make changes to the Arc objects, this changes will still take effect in both lists. If you dont want this, you have to copy your Arc objects too.

    ArrayList<ArrayList<Arc>> rotalar1 = new ArrayList<ArrayList<Arc>>();
    ArrayList<ArrayList<Arc>> rotalar2 = new ArrayList<ArrayList<Arc>>();

    for(ArrayList<Arc> list : rotalar1)
    {
        rotalar2.add(new ArrayList<Arc>(list));
    }

This is another way, using Collections.copy(dest,src)

    for(ArrayList<Arc> list : rotalar1)
    {
        ArrayList<Arc> copy = new ArrayList<>();
        Collections.copy(copy, list);  //or copy.addAll(list);
        rotalar2.add(copy);
    }

This problem is soved now:

rotalar2.get(random1).remove(random3);
rotalar2.get(random2).remove(random4);

but this will still take effect on both lists:

rotalar2.get(rndList).get(rndArc).set(xvy)

If you want to fix this problem too, you can do something like this:

    ArrayList<ArrayList<Arc>> rotalar1 = new ArrayList<ArrayList<Arc>>();
    ArrayList<ArrayList<Arc>> rotalar2 = new ArrayList<ArrayList<Arc>>();

    for(ArrayList<Arc> list : rotalar1)
    {
        ArrayList<Arc> tmpList = new ArrayList<>();
        for(Arc arcObj : list)
        {
            tmpList.add(copyOfyourArc); //TODO how do you want to creat a copy of Arc obj?
        }
        rotalar2.add(tmpList);
    }

You are not deep copying your list.

The problem is, that your lists contain references to objects. If you copy that (list of) refereces to your second list, both references (the original and the copied one) are pointing to the very same object. Every change applied to the object through the referenc in the second list, will be visible in the first list as well.

To deep copy the collection, you could eg iterate over it and manually copy each index.

You should implement your own method to do a deep copy within the Arc class. The method should create a new instance of the object and set all fields(attributes) to the value that the current object has. This method should return a new Object of type Arc that has all the same values as the object trying to be copied. You should then iterate over your arraylist(s) and use your copy method on each object and add the new object to a new arraylist which will be a copy of your original arraylist. Example:

//I don't know the attributes of your Arc class this is just an example

public Arc deepCopy()
{
    Arc copyOfArc = new Arc(this.field, this.field2, this.field3, this.field4, etc...);
    //if you don't set everything in the constructor then you should use your setters here.
    copyOfArc.setField5(this.Field5);
    etc...
    return copyOfArc;
}

Use this method to iterate over your arraylist and copy each arc object to a new arraylist.

Here is an example of using the deepCopy() method to copy your objects to new arraylist:

ArrayList<ArrayList<Arc>> rotalar2 = new ArrayList<ArrayList<Arc>>();
int counter = 0;

for(ArrayList<Arc> temp : rotalar1)
{
   rotalar2.add(new ArrayList<Arc>());
   for(Arc temp1 : temp)
   {
      rotalar2.get(counter).add(temp1.deepCopy());
   }
   counter++;
}

This will copy arraylist rotalar1 to arraylist rotalar2 with a deepCopy so each arraylist will have its own objects and won't effect each other anymore.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM