2016-08-10 7 views
-2

異なるオブジェクトの階層にわたって単一ループ反復を実装するにはどうすればよいですか? Javaの階層を超える単一反復8

は(私はforループを使用しているが、これらは、グリッドの異なる領域を表している - 。私はやっと大幅に物事を単純化する単一のループを使用した位置決めのために使用されるすべての値を追跡することができます。)

これをオブジェクトの階層は、編集

class Hierarchical < PT extends Hierarchical<?,?,?>,T,CT extends Hierarchical< ?, ?, ? >>{ 
    ObservableList<Hierarchical> children; //Zero or more objects.. 
} 

class Seed extends Hierarchical { /* never has children-objects */ } 
class Tree extends Hierarchical { ... } 
class Planet extends Hierarchical { ... } 

....私が持っているものです:惑星のインスタンスの子どもたちは木、種子を含む樹木も同じです。

...そしてこれは私が何をしたいです:

Planet p = new Planet(); //trees/seeds are instantiated internally. 
Iterator<?> itr = p.getChildren().iterator(); 
while (itr.hasNext()) { 
    Object obj = itr.next(); 
    if (obj instanceof Planet){ /* cast to Planet & do stuff */ } 
    if (obj instanceof Tree ){ /* cast to Tree & do stuff */ } 
    if (obj instanceof Seed ){ /* cast to Seed & do stuff */ } 
} 

は明らかに答えはIterator<?> itr = p.getChildren().iterator(); であるが、どのようにそれを実装することができますか?階層のどのレベルでも、子供たちが子どもたちの間を巡回するような場合には、その階層のすべてのレベルで子供の位置を保持する必要があるようです。それはずっと長く、私はもうデザインパターン& javaのコレクションに精通していない。 :(私は、pがタイプ惑星であるためIterator<Hierarchical> itr = p.getChildren().iterator();を使用しようとすると、私はエラーが発生したことに注意しましょう

編集:。これは、「深・ラスト」(...またはFIFOにする必要があります

+2

https://google.github.io/guava/releases/snapshot/api/docs/com/google/common/collect/TreeTraverser.html –

+0

ですから、全体のサブ階層を横断イテレータをしたいです特定のノードの?最初に深みを持たせたい、あるいは息をするようにしたいですか? – Andreas

+0

ありがとうAndreas。私はそれが「最初の」または「最後の」とは思わないが、代わりに「遭遇した」ものである。私はRamsayがすでに再帰を使ってまともな答えを投稿したと思う。私は結果に満足しているとは言いませんが、うまくいくはずです。 –

答えて

0

私が正しく理解していれば、オブジェクトグラフ内のすべてのオブジェクトを訪問し、オブジェクトごとに何かをしたいのですか?

各オブジェクトが共通のインタフェースを実装する場合、これは単純に、再帰。あなたの唯一の決定は、深さ優先の再帰を行うか幅優先を行うかです。深さのために

まず、あなたが

public void visit(Hierarchical h) { 
    // do something with h 
    Iterator<Hierarchical> children = h.getChildren(); 
    while(children.hasNext()) { 
     visit(children.next()); 
    } 
} 

よう

何かをしたいと思うことは、階層のすべてのレベルがそれの 位置を維持する必要があると思われる場合の子供たちの子供たちが通じ をループスタートですそれらの子どもたち

このように再帰を使用すると、「位置」を追跡する必要はありません。イテレータの状態は、メソッドを再度呼び出すとスタックに保持されますが、スタックが巻き戻されると、「シード」に到達すると、スタックのレベルをロールバックして、イテレータの次の繰り返しを呼び出します。

幅優先の場合は、最初にノード全体を処理して、ブランチを収集する必要があります。すべての子供の処理が終わったら、ブランチのコレクションを開始する必要があります。

public void visit(Hierarchical h) { 
    List<Hierarchical> branches = new LinkedList<>(); 
    Iterator<Hierarchical> children = h.getChildren(); 

    while(children.hasNext()) { 
     Hierarchical h = children.next(); 
     // do something with h 
     if(h.hasChildren()) { 
      branches.add(h); 
     } 
    } 

    for(Hierarchical branch : branches) { 
     visit(branch); 
    } 
} 
+0

UIでは深さ優先が機能しません。私が説明しなかった謝罪、これは複数の階層型変数を繰り返してグリッド上に表示することです。順序は重要です。 (元の投稿に編集を追加しました) –

+0

幅優先を含む回答が更新されました。 –

+0

はい、あなたは今何をしているのか分かります!ちょっと微調整すれば、うまくいくはずです。私はすぐに変更を掲載します。ありがとうございました。 = D –

関連する問題