Java 如何在没有堆栈溢出的情况下链接两个节点?

Java 如何在没有堆栈溢出的情况下链接两个节点?,java,methods,Java,Methods,我正在尝试将两个节点链接在一起。当n添加s作为链接时,s也应更新以添加n作为链接。但是代码调用自身,陷入无限循环,然后溢出。如何让节点彼此分配,而不是递归地分配它们自己 public class Node { Set<Node> connections = new HashSet<Node>(); public static void main(String args[]) { Node n = new Node(); N

我正在尝试将两个节点链接在一起。当
n
添加
s
作为链接时,
s
也应更新以添加
n
作为链接。但是代码调用自身,陷入无限循环,然后溢出。如何让节点彼此分配,而不是递归地分配它们自己

public class Node {
    Set<Node> connections = new HashSet<Node>();

    public static void main(String args[]) {
        Node n = new Node();
        Node s = new Node();
        n.addNode(s);
    }

    public Node() {

    }
    public void addNode(Node newNode) {
        connections.add(newNode);
        newNode.addNode(this);
    }
}

不要对此使用递归,这样就不会有问题

public void addNode(Node newNode) {
    connections.add(newNode);
    newNode.connections.add(this);
}

即使连接是私有的,这也是允许的,因为对字段和方法的访问是按类控制的,而不是按对象控制的。

您可以直接访问其他节点成员:

public void addNode(Node newNode) {
    connections.add(newNode);
    newNode.connections.add(this);
}
一种可以说是“更干净”的方法是将这种“逻辑”封装在一个方法中:

private void addConnection(Node newConnection) {
    connections.add(newConnection);
}

public void addNode(Node newNode) {
    addConnection(newNode);
    newNode.addConnection(this);
}

所以,我意识到了这一点,并考虑过这样做,但我很担心,因为这意味着
连接将被直接修改,而不会进行错误检查。使用受保护的方法设置它是否更好?我马上发布编辑。你可以在这个方法中添加任何你喜欢的错误检查。有趣。没有意识到
私有
名称仍然允许此操作。清楚地说,你是说对象A和对象B都可以修改彼此的私有变量,如果它们是相同的类型?酷。是的,这是正确的
private
仅将变量隐藏到其他类,而不是同一类的其他实例(有关说明和进一步链接,请参阅)。我认为,在类
X
中编写的代码可以访问在类
X
中声明的
private
成员。如果
Y
X
的子类,则类
Y
的对象可以具有来自这两个类的代码;但代码的编写位置决定了它可以看到哪些私有成员。是的,如果在类
X
中声明了一个私有成员,那么类
X
中的代码总是可以访问它,即使该成员属于与此
引用的对象不同的对象。直接方式的任何缺点,或者使用“更干净”方式的任何原因?缺点是混乱,更多的方法会使代码变得混乱。不过也有很多优点:您现在可以轻松插入日志、错误检查或将来的修改。您甚至可以完全交换内部数据结构,但对方法的调用将保持不变。@AlexG
addConnection
是私有的,这主要是风格问题。如果您将其设置为受保护,则需要为其设置一个参数,允许您扩展
节点
类,并允许不同的扩展类以不同的方式实现它。好的。明确地说,这将被另一个类扩展(它用于游戏级别的映射房间)。但他们根本不会修改代码,所以我认为它可以保持私密性。顺便说一句,我相信你的“直接”方法有点错误。应该是
newNode.connections.add(this)
。通过更新,您的问题似乎得到了解决。还有什么问题吗?好的,我得等一下暂停。啊,好的。只是被你对问题的编辑弄糊涂了。通常,您不会通过编辑将解决方案包含在问题中。因此,我认为你有一个后续问题。
private void addConnection(Node newConnection) {
    connections.add(newConnection);
}

public void addNode(Node newNode) {
    addConnection(newNode);
    newNode.addConnection(this);
}