【问题标题】:How to link two nodes without a stackoverflow?如何在没有stackoverflow的情况下链接两个节点?
【发布时间】:2018-03-24 21:50:58
【问题描述】:

我试图让两个节点链接在一起。当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);
    }
}

更新:我添加了此代码以使该方法调用另一个 setter 方法。

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

【问题讨论】:

  • 随着更新,您的问题似乎解决了。或者还有什么问题吗?
  • 一切都好,只好等待超时。
  • 啊,好吧。只是对您对问题的编辑感到困惑。通常,您不会通过编辑将解决方案包含在问题中。因此,我认为您有一个后续问题。

标签: java methods


【解决方案1】:

不要为此使用递归,你不会有问题。

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

即使connections 是私有的,这也是允许的,因为对字段和方法的访问是基于每个类而不是每个对象来控制的。

【讨论】:

  • 所以,我意识到这一点并考虑这样做,但我很担心,因为这意味着connections正在被直接修改,没有错误检查。使用受保护的方法来设置它会更好吗?我会在稍后发布一个编辑。
  • 您可以在此方法中添加您喜欢的任何错误检查。
  • 有趣。不知道 private 名称仍然允许它工作。要清楚,您是说对象 A 和对象 B 都可以修改彼此的私有变量,如果它们是相同的类型?酷。
  • 是的,这是正确的。 private 仅将变量隐藏到其他类,而不是同一类的其他实例(请参阅SO: Access private field of another object in same class 以获得解释和更多链接)。
  • 我的看法是,在X 类中编写的代码 可以访问在X 类中声明的private 成员。如果Y 是X 的子类,则Y 类的对象可以具有来自这两个类的代码;但它是编写代码的地方,它决定了它可以看到哪些私有成员。是的,如果在类X 中声明了一个私有成员,那么类X 中的代码始终可以访问它,即使该成员属于与this 引用的对象不同的对象。
【解决方案2】:

你可以直接访问对方的节点成员:

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);
}

【讨论】:

  • 直接方式有什么缺点,或者有什么理由使用“更清洁”的方式吗?
  • 缺点是混乱,更多的方法会使你的代码混乱。但是有很多优点:您现在可以轻松插入日志记录、错误检查或将来的修改。您甚至可以完全交换内部数据结构,但对方法的调用将保持不变。
  • @AlexG addConnection 是私有的,这主要是风格问题。如果您将其设置为受保护,则需要为它提供一个参数,允许您扩展 Node 类并允许不同的扩展类以不同的方式实现它。
  • 好的。需要明确的是,这将由另一个类扩展(它用于在游戏关卡中映射房间)。但他们根本不会修改代码,所以我认为它可以保持私密。顺便说一句,我相信你的“直接”方法有点不对劲。应该是newNode.connections.add(this)。
猜你喜欢
  • 1970-01-01
  • 2012-10-05
  • 1970-01-01
  • 2021-10-01
  • 2017-02-23
  • 1970-01-01
  • 2012-06-12
  • 2021-03-28
  • 2018-07-25
相关资源
最近更新 更多