有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java复制构造函数创建依赖副本

我实现了here中描述的复制构造函数。但问题仍然是,当我更新route_copy时,相同的更新应用于route。所以,我不明白我的代码中有什么错误

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'
}

共 (5) 个答案

  1. # 1 楼答案

    使用复制构造函数所做的只是使新的Route使用旧的Route列表,因此对其中一个的任何更改都会立即影响另一个

    您需要做的是让复制构造函数创建一个新列表:

    sites = new ArrayList<Site>(oldList);
    
  2. # 2 楼答案

    问题是两个列表仍然指向同一个内存位置,因此,对一个列表的任何操作最终都会修改另一个列表

    您可以尝试使用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.

    像这样:

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

    但是请注意,对列表中的Site对象进行任何修改都可能会对存储在其他列表中的其他对象进行重新循环,具体取决于Site对象的复杂程度

  3. # 3 楼答案

    您的“复制构造函数”没有复制输入列表。试试像这样的东西

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

    对于第二个构造函数

  4. # 4 楼答案

    在复制构造函数中,您只需执行浅复制,而需要执行深复制:

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

    这里,您仍然在复制list的引用,它仍然指向相同的ArrayList。您应该修改它以创建列表的副本。您可能还需要在arraylist中创建元素的副本,如下所示:

    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;
    }
    

    检查此帖子-Shallow Copy vs Deep Copy.

  5. # 5 楼答案

    当然,它将创建从属副本,也称为浅层副本

    您需要一份深入的副本