2017-01-12 5 views
0

親がクリックされたときにVaadinツリーの子アイテムを取得しようとしています。私はツリーを横断する別のメソッドを作成して再帰を使用しようとしていますが、私は立ち往生しています。これはこれまで私が持っているものです:Vaadinで再帰を使って子ツリー項目を取得する方法は?

public Collection<?> recursiveTreeSearch(Object objectItemID, Collection<?> siblings){ 

    if (evoltWebUI.getPrimaryTreeView().hasChildren(objectItemID)==true){ 

     siblings = evoltWebUI.getPrimaryTreeView().getChildren(objectItemID); 

     for (int i = 0; i < evoltWebUI.getPrimaryTreeView().getChildren(objectItemID).size(); i++) { 

      recursiveTreeSearch(objectItemID, siblings); 
     } 

    } 

    return siblings; 
}; 

これは無限ループに終わります。助言がありますか?

+0

私はあなたのツリーの兄弟の量を減らすことはないので、テストしないと思います....したがって、あなたのメソッドは同じパラメータで常に呼び出され、決して終了できません – endkugelfang

+0

私はevoltWebUIが変更/最終的にオブジェクトを何度も再帰しま​​す。それが子供を持っている場合、それは常に再発するでしょう。それは前に述べたようにしなければならないテストです – efekctive

+0

evoltWebUIをparamにします。現在の子に子があるかどうかをテストしてから再帰する – efekctive

答えて

1

子供たちだけでなく、の子孫(サブツリーのノード)をすべて取得しようとしている可能性があります。子供を簡単に取得するにはgetChildren()で十分でしょう。専門用語についてはhttps://en.wikipedia.org/wiki/Tree_(data_structure)#Terminologyをご覧ください。

同じパラメータを使用して同じメソッドを再帰的に呼び出すことが問題です。あなたが意味することは、おそらく次のようである:

public Collection<?> recursiveTreeSearch(Object objectItemID, Collection<?> siblings){ 

     if (evoltWebUI.getPrimaryTreeView().hasChildren(objectItemID)==true){ 
      // here you had an issue as well, as your line in fact did nothing visible to the caller 
      siblings.addAll(evoltWebUI.getPrimaryTreeView().getChildren(objectItemID)); 

      for (int i = 0; i < evoltWebUI.getPrimaryTreeView().getChildren(objectItemID).size(); i++) { 
       // here was your bug: 
       recursiveTreeSearch(evoltWebUI.getPrimaryTreeView().getChildren(objectItemID).get(i), siblings); 
      } 
     } 

     return siblings; 
    }; 

これは無限ループを生成し、望ましい結果を返すべきではありません。このように使用します。recursiveTreeSearch(itemId、new ArrayList())。メソッドを作るために

は見た目が良く、わずかに、より効率的なあなたは、子どもたちがローカル変数にオブジェクトを抽出し、foreachループを使用し、より良い方法やパラメータに名前を付ける必要があります。

public Collection<?> getDescendants(final Object itemId) { 
     return getDescendantsRec(itemId, new ArrayList<Object>()); 
    } 

    private Collection<?> getDescendantsRec(final Object itemId, final Collection<Object> siblings) { 

      Collection<?> childrenIds = evoltWebUI.getPrimaryTreeView().getChildren(itemId); 

      if (childrenIds.size() > 0){ 
       siblings.addAll(childrenIds); 

       for (Object childItemId : childrenIds) { 
        getDescendantsRec(childItemId, siblings); 
       } 
      } 

      return siblings; 
     }; 

・ホープ、このことができます。

+0

これは役に立ちます私に再帰をより明確にする。しかし私は "siblings.addAll(childrenIds);" childrenidsコレクションに兄弟コレクションを追加することは望ましくありません。 "Collection のメソッドaddAll(Collection <?extends capture#4-of?>)は引数には適用されません(Collection )」と表示されます。なにか提案を? – PeachesToad

+0

また、forループのitemIdには重複する変数名として下線が引かれています。これはitemId2か別の名前のものでなければなりませんか? – PeachesToad

+0

「コレクション childrenIds = evoltWebUI.getPrimaryTreeView()。getChildren(itemId);」というエラーが発生しました。それは言う:「タイプの不一致:コレクションから回収することはできません」キャプチャ#2-of?>コレクション "。また、子供を迎える準備ができたら、itemIDだけでgetDescendantsを呼び出すだけですあれは正しいですか? – PeachesToad

関連する問題