分享

简单的Java对象没有深度复制

 印度阿三17 2019-06-20

对于任何Java开发人员来说,这个问题应该很容易.我发誓我在花了大约2个小时后查了一下,但我真的不明白这段代码有什么问题.

基本上,我正在实施Karger的最小割算法.它需要我在图中合并节点,然后计算结尾的交叉边数(一个int值).该算法必须重复n次,始终从起始图开始.我的问题是我无法创建我的Graph对象的深层副本,我找不到错误.

我已经裁剪了代码只是为了显示问题,而不是更多,但我仍然无法弄清楚出了什么问题.这里的代码是.

类节点:

public class Node {
public Integer Data;


public Node() {
    Data = 0;
}

public Node(Node rhs) {
    Data = rhs.Data.intValue();
}

public Node(Integer rhs) {
    Data = rhs.intValue();
}

public void setNode(Integer rhs) {
    Data = rhs;
}

类图:

public class Graph {

public ArrayList<ArrayList<Node>> AdjList;
public ArrayList<Node> NodeSet; // This contains all the nodes

public Graph() {
    AdjList = new ArrayList<ArrayList<Node>>();
    NodeSet = new ArrayList<Node>();
}

public Graph(Graph G) {
    AdjList = new ArrayList<ArrayList<Node>>();
    for (ArrayList<Node> L : G.AdjList) {
        ArrayList<Node> Lcopy = new ArrayList<Node>();
        for (Node N : L) {
            Node copy = new Node(N);
            Lcopy.add(copy);
        }
        AdjList.add(L);
    }
}
    public void addNewAdjList(ArrayList<Node> NodeAdjList) {
    // Input is the adjacency list of a new node
    // The first element in the NodeAdjList is the node itself, the rest is the adj nodes
    AdjList.add(NodeAdjList);
}
public static void printAdjList(ArrayList<Node> Adjlist) {
    Node start = Adjlist.get(0);
    System.out.print(start.Data   " : ");
    for (int j=1; j < Adjlist.size();   j) {
        System.out.print(Adjlist.get(j).Data   ", ");
    }
    System.out.print("\n");
}

主要:

public class Main {

/**
 * @param args
 */
public static void main(String[] args) {
    Node Five = new Node(5);
    Node Seven = new Node(7);
    Node One = new Node(1);

    Graph G = new Graph();

    ArrayList<Node> L = new ArrayList<Node>();
    L.add(Five);
    L.add(Seven);
    L.add(One);

    G.addNewAdjList(L);

    Graph R = new Graph(G);
    R.AdjList.get(0).get(1).setNode(19); // Gets node #1 in the first adj list, i.e. 7

    Graph.printAdjList(G.AdjList.get(0));
    Graph.printAdjList(R.AdjList.get(0));

}

}

输出:

5 : 19, 1,

5 : 19, 1,

说实话,这让我很困惑.我知道Java只是按值传递,但对象总是由它们的引用表示.据我所知,我的G复制构造函数应该总是做一个深层复制:我正在遍历每个邻接列表,然后我正在制作一个Node的深层副本.我不明白为什么在复制的对象上调用.setNode()也会修改原始对象(具有不同的引用).

1这样的先前答案似乎与我要走的方向相同,我在这里缺少什么? :S

解决方法:

你的错误在这里:

ArrayList<Node> Lcopy = new ArrayList<Node>();
for (Node N : L) {
    Node copy = new Node(N);
    Lcopy.add(copy);
}
AdjList.add(L);

您创建了L的副本(称为Lcopy),但随后将原始L添加到克隆的图形中.要修复它,最后一行应该是这样的:

AdjList.add(Lcopy);

注意:如果您为变量使用了合理的名称而不是L,则此错误可能永远不会发生!

来源:https://www./content-1-253651.html

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多