Recursion 使用Java8流汇总树节点

Recursion 使用Java8流汇总树节点,recursion,java-8,java-stream,Recursion,Java 8,Java Stream,如果可能的话,是否可以使用Java8流对树的节点进行汇总(如果可能的话),以一行的形式 这是一个节点类 public class Node { private int nodeNum; ArrayList<Node> children = new ArrayList<>(); public Node(int num) { this.nodeNum = num; } public int getNodeNum() { return node

如果可能的话,是否可以使用Java8流对树的节点进行汇总(如果可能的话),以一行的形式

这是一个节点类

public class Node
{   
private int nodeNum;    
ArrayList<Node> children = new ArrayList<>();

public Node(int num)
{
    this.nodeNum = num;
}

public int getNodeNum()
{
    return nodeNum;
}

public boolean addNode(Node node)
{
    return children.add(node);
}

public ArrayList<Node> getNodes()
{
    return this.children;
}
}
我们可以使用流来总结直接的子节点,但我不知道如何使用流来深入并递归地进行。 这段代码只在一个层次上解决了这个问题。有什么想法吗

total = list.stream().filter(Node -> node.children.isEmpty()).map(Node:: getNodeNum).reduce(node.getNodeNum(), (a,b) -> a+b);

解决您的问题的一个方法是使用递归

首先,需要将以下帮助器方法添加到节点类中:

这将使用上述定义的Node.allChildren方法以及和方法来计算总和

或者,您可以在节点类中有一个执行递归的函数子体属性:

private Function<Node, Stream<Node>> descendants =
    node -> Stream.concat(
        Stream.of(node),
        node.children.stream()
            .flatMap(this.descendants)); // recursion here: function invoked again
最后,getNodeSum方法的代码与以前的版本相同:

int getNodeSum(Node node) {
    return node.allChildren()
        .mapToInt(Node::getNodeNum)
        .sum();
}

注意:虽然这种方法可能对某些人很有吸引力,但它可能有一些缺点,即现在节点类的每个实例都有“后代”属性,尽管根本不需要。您可以通过将此递归函数作为属性的树类和删除了子类属性的内部类的节点来避免这种情况。

您需要为节点类添加递归方法,该方法将连接子流

public Stream<Node> recursiveConcat() {
    return Stream.concat(
        Stream.of(this),
        children.stream().flatMap(Node::recursiveConcat));
}
全部代码

public class Node {

    private int nodeNum;
    ArrayList<Node> children = new ArrayList<>();

    public Node(int num) {
        this.nodeNum = num;
    }

    public int getNodeNum() {
        return nodeNum;
    }

    public boolean addNode(Node node) {
        return children.add(node);
    }

    public ArrayList<Node> getNodes() {
        return this.children;
    }

    public Stream<Node> recursiveConcat() {
        return Stream.concat(
                Stream.of(this),
                children.stream().flatMap(Node::recursiveConcat));
    }
}


Node root = new Node(1);
Node node1 = new Node(2);
Node node2 = new Node(3);
Node node3 = new Node(4);
node2.addNode(node3);
node1.addNode(node2);
root.addNode(node1);
System.out.println(root.recursiveConcat().mapToInt(Node::getNodeNum).sum());
public Stream<Node> allChildren() {
    return descendants.apply(this);
}
int getNodeSum(Node node) {
    return node.allChildren()
        .mapToInt(Node::getNodeNum)
        .sum();
}
public Stream<Node> recursiveConcat() {
    return Stream.concat(
        Stream.of(this),
        children.stream().flatMap(Node::recursiveConcat));
}
root.recusiveConcat().mapToInt(Node::getNodeNum).sum()
public class Node {

    private int nodeNum;
    ArrayList<Node> children = new ArrayList<>();

    public Node(int num) {
        this.nodeNum = num;
    }

    public int getNodeNum() {
        return nodeNum;
    }

    public boolean addNode(Node node) {
        return children.add(node);
    }

    public ArrayList<Node> getNodes() {
        return this.children;
    }

    public Stream<Node> recursiveConcat() {
        return Stream.concat(
                Stream.of(this),
                children.stream().flatMap(Node::recursiveConcat));
    }
}


Node root = new Node(1);
Node node1 = new Node(2);
Node node2 = new Node(3);
Node node3 = new Node(4);
node2.addNode(node3);
node1.addNode(node2);
root.addNode(node1);
System.out.println(root.recursiveConcat().mapToInt(Node::getNodeNum).sum());