2017-10-12 80 views
2

我試圖讓兩個節點鏈接在一起。當n作爲鏈接添加s時,s也應更新爲添加n作爲鏈接。但代碼自行調用並陷入無限循環,然後溢出。我怎樣才能讓節點相互分配,但不能遞歸地分配自己?如何在沒有stackoverflow的情況下鏈接兩個節點?

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

隨着更新你的問題似乎**解決**。還是有問題嗎? – Zabuza

+0

一切順利,不得不等待暫停。 –

+0

啊好的。剛剛被你編輯的問題弄糊塗了。通常情況下,您不會通過編輯在解決方案中包含解決方案。因此,我認爲你有一個後續問題。 – Zabuza

回答

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

直接方式或使用「更清潔」方式的任何理由有什麼缺點? –

+2

不利的方面是**混亂**,更多的方法可能會混淆你的代碼。但是有很多優點:您現在可以輕鬆插入日誌記錄,錯誤檢查或將來的修改。您甚至可以完全交換內部數據結構,但對該方法的調用將保持不變。 – Zabuza

+1

@AlexG由於'addConnection'是私人的,它主要是風格問題。如果你將它保護起來,就有一個參數可以讓你擴展'Node'類並允許不同的擴展類以不同的方式實現它。 – Mureinik

5

不要爲此使用遞歸,而且你也不會有問題。

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

這是允許的,即使connections是私有的,因爲訪問字段和方法是在每個階級基礎,不是每個對象爲基礎的控制。

+0

所以,我意識到這一點,並考慮過這樣做,但我很擔心,因爲這意味着連接被直接修改,沒有錯誤檢查。使用受保護的方法來設置它會更好嗎?我會在一秒後發佈一個修改。 –

+1

您可以將任何錯誤添加到您喜歡的方法中。 –

+1

有趣。沒有意識到'私人'的指定仍然允許這個工作。清楚的是,你是說對象A和對象B都可以修改對方的私有變量,如果它們是相同的類型?涼。 –

相關問題