3

次のようなクラスがあります。

public class Node {
    private final Node otherNode;
    public Node(Node otherNode) {
        this.otherNode = otherNode;
    }
}

のようなことをしたい

Node n1, n2 ;
n1 = new Node(n2);
n2 = new Node(n1);

ただし、n2 はまだ初期化されていないため、明らかにできません。セッターを使用して otherNode を設定したくないのは、それが最終的なものであるためです。したがって、一度だけ設定する必要があります。これを達成するための最もクリーンなアプローチは何ですか? これを行うのに慣れていない派手な Java 構文はありますか? コンストラクターに加えて初期化メソッドを使用する必要がありますか (醜い)、または単純に洞窟に入ってセッターを使用する必要がありますか (これも醜い)?

4

2 に答える 2

9

パラメーターをとらず、独自の を構築し、自分自身Nodeを相手の「その他」として渡す 2 番目のコンストラクターを用意します。

public class Node
{
   private final Node otherNode;

   public Node(Node other)
   {
      otherNode = other;
   }

   public Node()
   {
      otherNode = new Node(this);
   }

   public Node getOther()
   {
      return otherNode;
   }
}

次に、それを使用する場合:

Node n1 = new Node();
Node n2 = n1.getOther();

それらが互いに参照していることを保証します。

System.out.println(n1 == n1.getOther().getOther());
System.out.println(n2 == n2.getOther().getOther());
System.out.println(n1 == n2.getOther());
System.out.println(n2 == n1.getOther());

これらはすべて印刷されますtrue

于 2013-05-23T23:58:07.080 に答える
2

(これは rgettman の回答の補足です。)

より一般的な解決策は、次のようなコンストラクターを作成することです。

private Node(final int numNodesInLoop) {
    if(numNodesInLoop < 1) {
        throw new IllegalArgumentException();
    }
    Node head = this;
    for(int i = 1; i < numNodesInLoop) {
        head = new Node(head);
    }
    this.otherNode = head;
}

2 つのノードを持つケースは、 としてインスタンス化されnew Node(2)ます。

privatergettman の回答に対する user949300 のコメントに従って、上記を作成しました。なぜなら、を受け取るNodeコンストラクターの意味intはあまり推測できないためです (ループを作成しますか?!) static。機能クリア:

public static Node newNodeLoop(final int numNodes) {
    return new Node(numNodes);
}

(これは、後で何らかの理由で , を取る別のコンストラクターが必要になった場合に備えて、より将来性のあるものでもありますint。その後、このコンストラクターを変更して、コンパイラーにどのコンストラクターを使用するかを伝えるのに十分な仮引数を取ることもできます。ファクトリ メソッドは同じコントラクトを保持します)。

于 2013-05-24T15:57:58.240 に答える