【问题标题】:Java - Return a list with recursionJava - 返回一个递归列表
【发布时间】:2015-08-06 11:23:03
【问题描述】:

我需要在特定节点之后返回所有子节点的列表。这是我所做的 -

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;
    }

但它不起作用并且没有正确添加所有子项。

【问题讨论】:

    标签: java android list recursion


    【解决方案1】:

    您没有添加有孩子的孩子。

    您需要将循环更改为:

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

    即无论它是否有孩子,您都应该始终添加childObj

    我还将childObj 的添加移动到添加其子节点之前,假设这是您希望节点出现的顺序(即首先是父节点,然后是子节点)。

    此外,如上所述,循环内不应有 return 语句,因为它会跳过添加除第一个子项之外的所有子项。 return 语句应该在循环之后。

    【讨论】:

    • 谢谢伊兰。它仍然有一个错误。我没有错,但它仍然没有将所有孩子都添加到列表中。
    • 它只返回第一个元素的子元素列表。
    • 您能否稍微修改一下您的答案,我会接受。所以,问题出在方法调用之前的 return 语句。这将使该方法只返回第一个孩子的孩子。
    • @sayed 哦,我完全错过了。谢谢。我将编辑我的答案。
    【解决方案2】:

    如果您的方法已经返回它,则您不需要一个包含返回对象的额外列表。你仍然想要然后你可以使用它。否则,您的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;
                    }
    

    您只需要添加当前的非空子项,并为所有子项调用相同的方法来提取他们的子项并将所有添加到同一个列表中

    【讨论】:

    • 不会在递归过程中每次调用该方法时创建一个新列表吗?所以我们会忘记之前的所有元素??
    • 是的,这将为树中的每个级别创建一个新列表。
    • 您不会丢失任何东西,因为在一端您的方法包含所有元素。如果您看到第一次执行方法会保留其他调用返回的所有元素。
    【解决方案3】:

    你不添加头节点:

      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;
    }
    

    【讨论】:

      【解决方案4】:

      给出的答案没有错,但我想我会稍微改变一下。如果可能的话,我更喜欢避免循环内的条件,你可以稍微重新排列代码。在下面的示例中,我展示了 Java 8 lambda 版本和 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+"}";
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2014-01-18
        • 2015-06-25
        • 1970-01-01
        • 1970-01-01
        • 2021-07-21
        • 2014-12-25
        • 2020-01-22
        • 2020-02-23
        相关资源
        最近更新 更多