2015-08-06 3 views
1

Мне нужно вернуть список всех дочерних элементов после определенного узла. Вот что я сделал -Java - Возврат списка с рекурсией

public List<Object> getChildrenTree(Object currentObject, List<Object> returnList){ 

     //get all child-URIs for the category 
     List<Object> objectChildren = currentObject.getChildren(); 

     for (Obj childObj : objectChildren) { 

      if(childObj !=null){ 

       if(childObj.getChildren().size() >0){ 
        getChildrenTree(childObj,returnList); 
       }else{ 
        returnList.add(childObj); 
       } 
      } 
     } 

     return returnList; 
    } 

но он не работает и не добавляет всех детей должным образом.

ответ

3

Вы не добавили детей, у которых есть дети.

Вы должны изменить свой цикл, чтобы:

for (Obj childObj : objectChildren) { 
     if(childObj !=null){ 
      returnList.add(childObj); 
      if(childObj.getChildren().size() >0){ 
       getChildrenTree(childObj,returnList); 
      }    
     } 
    } 
    return returnList; 

т.е. вы всегда должны добавить childObj, независимо от того, имеет ли он или нет детей.

Я также переместил добавление childObj перед добавлением его дочерних элементов, считая, что это тот порядок, по которому вы хотите, чтобы узлы отображались (то есть сначала родительский, а затем дети).

Кроме того, как упоминалось выше, в цикле не должно быть оператора return, так как оно пропускает добавление всех, кроме первого ребенка. Оператор return должен быть после цикла.

+0

Спасибо Эран. У него все еще есть ошибка. Я не ошибаюсь, но он все еще не добавляет всех детей в список. –

+0

возвращает только список дочерних элементов для первого элемента. –

+0

не могли бы вы немного изменить свой ответ, и я приму это. Таким образом, проблема заключалась в возврате оператора перед вызовом метода. Это заставит метод возвращать только детей первого ребенка. –

1

Вам не нужен дополнительный список, содержащий возвращаемые объекты, если ваш метод уже возвращает его. Тем не менее вы хотите, чтобы вы могли его использовать. В противном случае под изменениями кода для вашего if будет работать нормально.

 public List<Object> getChildrenTree(Object currentObject){ 

        //get all child-URIs for the category 
        List<Object> returnList=new ArrayList<Object>(); 
        List<Object> objectChildren = currentObject.getChildren(); 

        for (Object childObj : objectChildren) { 

         if(childObj !=null){ 
       // add current child 
          returnList.add(childObj); 
      if(!childObj.getChildren().isEmpty()){ 
      // invoke recursive to extract childs of current object and add them to list. 
//That's all childs you need 
          returnList.addAll(getChildrenTree(childObj)); 
      } 
         } 
        } 

        return returnList; 
       } 

Что вам нужно просто добавить текущие не-нуль Чайлдс и для всех Чайлдс вызывать тот же метод, чтобы извлечь их Чайлдс и addAll в этом же списке

+0

Не создавайте новый список при каждом вызове метода во время рекурсии? поэтому мы потеряем все предыдущие элементы? –

+0

Да, это создает новый список для каждого уровня в дереве. – MadConan

+0

вы ничего не потеряете, потому что на одном конце ваш метод содержит все элементы. Если вы видите, что первое выполнение метода сохраняет все возвращенные элементы из других вызовов. –

0

Вы не добавить узел головки:

public List<Object> getChildrenTree(Object currentObject, List<Object> returnList){ 

    returnList.add(currentObject); 
    //get all child-URIs for the category 
    List<Object> objectChildren = currentObject.getChildren(); 

    for (Obj childObj : objectChildren) { 
     if(childObj !=null){ 
      if(childObj.getChildren().size() >0){ 
       return getChildrenTree(childObj,returnList); 
      }    
     } 
    } 

    return returnList; 
} 
0

Ничего плохого в ответах не было, но я думал, что дам небольшое изменение. Я предпочитаю избегать условностей внутри цикла, если это возможно, что вы можете с некоторой перестановкой кода. В следующем примере я показываю как версию Java 8 лямбда, так и предварительную Java 8. В этом случае код Java 8 на самом деле ничего не купит вам, но я все равно туда бросил.

Я создал пользовательский класс Node для того, чтобы увидеть выход

public class ListAdd { 

    public static void main(String[] args) { 
     Node node = new Node(0); 
     addChildren(3,node); 
     addChildren(4,node.getChildren().get(0)); 
     addChildren(2,node.getChildren().get(2)); 
     addChildren(1,node.getChildren().get(2).getChildren().get(0)); 
     addChildren(2,node.getChildren().get(2).getChildren().get(0).getChildren().get(0)); 

     List<Node> allNodes = getAllNodes(node,new ArrayList<>()); 
     System.out.println("------------------------\nTotal number of nodes: " + allNodes.size()); 
     allNodes.forEach(System.out::println); 

     allNodes = getAllNodesOld(node, new ArrayList<>()); 
     System.out.println("------------------------\nTotal number of nodes: " + allNodes.size()); 
     allNodes.forEach(System.out::println); 
    } 

    public static List<Node> getAllNodes(Node parent, List<Node> allNodes){ 
     if(parent == null || parent.getChildren().size() < 1){ 
      return allNodes; 
     } 
     parent.getChildren() 
      .forEach(node -> { 
      allNodes.add(node); 
      getAllNodes(node,allNodes); 
      }); 
     return allNodes; 
    } 

    public static List<Node> getAllNodesOld(Node parent, List<Node> allNodes){ 
     if(parent == null || parent.getChildren().size() < 1){ 
      return allNodes; 
     } 

     for(Node node : parent.getChildren()){ 
      allNodes.add(node); 
      getAllNodesOld(node, allNodes); 
     } 
     return allNodes; 
    } 

    public static void addChildren(int amount, Node parent){ 
     for(int i=0;i<amount;i++){ 
      parent.addChild(new Node(i + (parent.getVal() + 1))); 
     } 
    } 

    public static class Node{ 
     List<Node> children = new ArrayList<>(); 
     int val; 

     public Node(int v){ 
      val = v; 
     } 

     public void addChild(Node node){ 
      children.add(node); 
     } 

     public List<Node> getChildren(){ 
      return children; 
     } 

     public int hashCode(){ 
      return 31 * val * (children.size() + 1); 
     } 

     public int getVal(){ 
      return val; 
     } 

     public boolean equals(Object o){ 
      if(o == this) return true; 
      if(!(o instanceof Node)) return false; 
      Node n = (Node)o; 
      return val == n.val && children.containsAll(n.children); 
     } 

     public String toString(){ 
      return "Node{val="+val+",children="+children+"}"; 
     } 
    } 
} 
Смежные вопросы