树遍历和一阶函数

时间:2013-06-26 22:59:11

标签: java generics tree traversal higher-order-functions

假设我有一个Tree类和一个Node类

public class Tree{
    private Node root;
    public Tree(Node root){ this.root = root; }
}

public class Node{
    private ArrayList<Node> children;
    private Node parent;
    private String label;
    private String someInfo;
    private int someIntegerInfo;
    private MyObject someObject;   // Where MyObject is from some other class
    ...

    public Node(Node parent, ArrayList<Node> children, String label, String foo, ...){
        this.parent = parent;
        this.children = children;
        this.someInfo = foo;
        ...
    }
}

现在假设我需要对这些Tree对象进行深度优先遍历以提取信息。也许我想做一次在访问时构建所有Node标签的字符串,另一次我想在int字段上执行某些操作等。

当我正在编写这些遍历时,我当然注意到我正在编写相同的代码来重复遍历,但是在节点上执行不同的操作或返回不同的类型。

public something traverse(Node node, something foo){
    // Do some stuff with foo here
    ...
    for( Node child: node.getChildren() ){
        return child.traverse();
    }
    return foo;
}

有没有一种方法可以让Java拥有一个只执行遍历的函数,但是接受一个更高阶的函数作为一个参数来处理我正在尝试获取的任何类型的信息?或者有没有更好的方法来做到这一点,我没想到?

1 个答案:

答案 0 :(得分:2)

您可以将操作封装到Java类中:

public interface NodeOperation {
   void perform(Node node);
}

public void traverse(Node node, NodeOperation op) {
    op.perform(node);
    for(Node child: node.getChildren()) {
        traverse(child, op);
    }
}

//then for performing the operation during the traversal call following code
traverse(node, new NodeOperation() {
   perform(Node node) {
      // do whatever you want
      node.setSomeIntegerInfo(node.getSomeIntegerInfo() * 42);
   }
});

在Java 8中,有一种更好的方法可以使用闭包来实现这一点。