简体   繁体   English

Java,执行构成有向图的节点的ArrayList的深层副本

[英]Java, Performing a deep, deep copy of a ArrayList of Nodes that make up a directed graph

I am having issues performing a copy of a Java ArrayList containing Node objects. 我在执行包含Node对象的Java ArrayList的副本时遇到问题。 These Node s have a HashSet<Edge> of Edge objects that point to other Node s in the ArrayList to form a directed graph. 这些NodeEdge对象的HashSet<Edge>指向ArrayList中的其他Node ,以形成有向图。 I need to make a copy of this ArrayList while maintaining the directed graph struture so that I can traverse the copied list just the same as I can with the original list. 我需要在保持有向图结构的同时复制此ArrayList,以便可以遍历复制的列表,就像使用原始列表一样。

The problem is that my deep copy of the list is not "deep" enough. 问题是我的深层列表不够“深层”。 When I copy the array in the method (below) the copies of the Node objects still point to the Nodes in the original array and not in the new array. 当我在下面的方法中复制数组时, Node对象的副本仍然指向原始数组中的Node,而不是新数组中的Node

How could I change the cloneList function so that it performs a deep, deep copy of the array so that it maintains the directed graph structure in the output array? 我该如何更改cloneList函数,以便执行数组的深层深复制,以便在输出数组中维护有向图结构?

public static ArrayList<Node> cloneList(ArrayList<Node> inList)
{
    ArrayList<Node> clonedList = new ArrayList<Node>(inList.size());
    for(Node aNode : inList)
    {
        clonedList.add(new Node(aNode));
    }
    return clonedList;
}

Node 节点

import java.util.ArrayList;
import java.util.HashSet;

public class Node
{
    public String name;
    public HashSet<Edge> inEdges;
    public HashSet<Edge> outEdges;
    public ArrayList<String> deps;

    public Node(String name, ArrayList<String> deps) {
        this.name = name;
        inEdges = new HashSet<Edge>();
        outEdges = new HashSet<Edge>();

        this.deps = deps;
    }
    public Node addEdge(Node node){
        Edge e = new Edge(this, node);
        outEdges.add(e);
        node.inEdges.add(e);
        return this;
    }
    @Override
    public String toString() {
        return name;
    }

    //Used to copy a given node
    public Node(Node inNode)
    {
        this.name = inNode.name;
        this.inEdges = (HashSet<Edge>)inNode.inEdges.clone();
        this.outEdges = (HashSet<Edge>)inNode.outEdges.clone();
        this.deps = inNode.deps;
    }
}

Edge 边缘

public class Edge
{
    public Node from;
    public Node to;
    public Edge(Node from, Node to) {
        this.from = from;
        this.to = to;
    }
    @Override
    public boolean equals(Object obj) {
        Edge e = (Edge)obj;
        return e.from == from && e.to == to;
    }
}

Override the clone function in Node and edge to use deep clones ( obj.clone() ) of the contained objects. 覆盖Node和edge中的克隆函数,以使用所包含对象的深层克隆( obj.clone() )。 For example, for Edge , you can use 例如,对于Edge ,您可以使用

 public Edge clone(){
      return new Edge(from.clone(), to.clone());
 }

(provided that you give a clone function for Node). (前提是您为Node提供了克隆功能)。

Then the only issue is collections (Strings are immutable, do not need to be cloned). 然后唯一的问题是集合(字符串是不可变的,不需要克隆)。 Use something along the lines of the solution provided in How to clone ArrayList and also clone its contents? 使用如何克隆ArrayList以及它的内容中提供的解决方案的方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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