Java - 返回带递归的列表

时间:2015-08-06 11:23:04

标签: java android list recursion

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

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

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

4 个答案:

答案 0 :(得分: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语句应该在循环之后。

答案 1 :(得分: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添加到相同的列表

答案 2 :(得分: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;
}

答案 3 :(得分:0)

给出的答案没有错,但我想我会稍微改变一下。我希望尽可能避免循环内的条件,你可以稍微重新排列代码。在下面的示例中,我展示了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+"}";
        }
    }
}