The copy constructor creates dependent copy

落花浮王杯 提交于 2019-12-31 03:51:15

问题


I implemented the copy constructor as it is described here. But still the problem is that when I update route_copy, then the same update is applied to route. So, I don't understand what is wrong in my code?

public class Route implements Comparable<Route> {
    private List<Site> sites;

    public Route()
    {
        sites = new ArrayList<Site>();
    }

    public Route(List<Site> sites)
    {
        this.sites = sites;
    }

    /**
     * Copy constructor
     */
    public Route(Route r) {
        this(r.sites);
    }

    public void deleteSite(Site s) {
        this.sites.remove(s);
    }
}

public processData(Route route)
{
  Route route_copy = new Route(route);
  Site s = selectSite(route_copy);
  route_copy.deleteSite(s); // !!! now 'route' does not contain an  element 's'
}

回答1:


In your copy constructor, you are just doing a shallow copy, while you need to do a deep copy:

public Route(Route r) {
    this(r.sites);
}

Here, you are still copying the reference of the list, which still points to the same ArrayList. You should modify it to create copy of list too. Possibly, you also need to create copy of the elements inside the arraylist like so:

public Route(Route r) {
    List<Site> newSites = new ArrayList<Site>();

    for (Site obj: r.sites) {
        // Add copy of obj to the newSites
        // So you need yet another copy constructor in 'Site' class.
    }

    this.sites = newSites;
}

Check this post - Shallow Copy vs Deep Copy.




回答2:


Your "copy constructor" is not making a copy of the input list. Try something like

public Route(List<Site> sites)
{
    this.sites = new ArrayList<Site>(sites);
}

for your second constructor.




回答3:


Ofcourse it'll create dependent copy also called Shallow copy.

You need a Deep copy.




回答4:


The problem is that both lists are still pointing to the same memory location, thus, any operation on one list eventually modifies the other.

You can try and use the copy constructor of the ArrayList:

public ArrayList(Collection c)

Constructs a list containing the elements of the specified collection, in the order they are returned by the collection's iterator.

Like so:

     public Route(Route r) {
     this(new ArrayList<Site>(r.sites));
     }

Note however that doing any modifications to the Site objects within the list might have repurcussions on the other objects stored in the other list, depending on how complex your Site object is.




回答5:


what you do with the copy constructor is just make the new Route use the list of the old Route and therefor any change to one of them immediately effect the other

what you need to do is make the copy constructor make a new list:

sites = new ArrayList<Site>(oldList);


来源:https://stackoverflow.com/questions/17703067/the-copy-constructor-creates-dependent-copy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!