java - 添加新元素时应该使用克隆吗?什么时候应该使用克隆?

标签 java memory class

我想用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/

相关文章:

java - 在应用程序中显示来自 EditTextPreference 的文本?

java堆大小增加并且内存不足

java - Swing JTextField 文本更改监听器 DocumentListener 无限循环

java - MS_Access中如何比较Integer类型记录和String类型记录?

java - String 和 HashSet 之间用于检查重复项的最佳(性能 + 内存)是什么

c++ - 在 C++ 中操作 vector 时出现段错误

C++。类方法指针

java - 链接到开始按钮的类不会运行

java - 在字符串比较期间将 String.charAt 减少到一个循环

java - 加载到内存中的文件比磁盘上的文件大