我想用Java实现一个类来处理图形数据结构。我有一个 Node 类和一个 Edge 类。 Graph 类维护两个列表:节点列表和边列表。每个节点必须有一个唯一的名称。我该如何防范这样的情况:
Graph g = new Graph();
Node n1 = new Node("#1");
Node n2 = new Node("#2");
Edge e1 = new Edge("e#1", "#1", "#2");
// Each node is added like a reference
g.addNode(n1);
g.addNode(n2);
g.addEdge(e1);
// This will break the internal integrity of the graph
n1.setName("#3");
g.getNode("#2").setName("#4");
我相信在将节点和边添加到图中时应该克隆它们,并返回一个 NodeEnvelope 类来维护图结构的完整性。这是这样做的正确方法还是设计从一开始就被破坏了?
最佳答案
我经常使用 Java 中的图形结构,我的建议是使图形依赖于维持其结构的 Node 和 Edge 类的任何数据成员成为最终的,而不使用 setter。事实上,如果可以的话,我会让 Node 和 Edge 完全不可变,其中有 many benefits .
例如:
public final class Node {
private final String name;
public Node(String name) {
this.name = name;
}
public String getName() { return name; }
// note: no setter for name
}
然后您将在 Graph 对象中进行唯一性检查:
public class Graph {
Set<Node> nodes = new HashSet<Node>();
public void addNode(Node n) {
// note: this assumes you've properly overridden
// equals and hashCode in Node to make Nodes with the
// same name .equal() and hash to the same value.
if(nodes.contains(n)) {
throw new IllegalArgumentException("Already in graph: " + node);
}
nodes.add(n);
}
}
如果需要修改节点名称,请删除旧节点并添加新节点。这可能听起来像是额外的工作,但它可以节省大量精力来保持一切顺利。
实际上,从头开始创建自己的图形结构可能是不必要的——如果您构建自己的图形结构,这个问题只是您可能遇到的许多问题中的第一个。
我建议找到一个好的开源 Java 图形库,并使用它。根据您正在做什么,有几种选择。我用过JUNG过去,并会推荐它作为一个很好的起点。
关于java - 添加新元素时应该使用克隆吗?什么时候应该使用克隆?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63748/