我喜欢使数据类不可变以使并发编程更容易。但是,使完全不变的层次结构似乎是有问题的。

考虑这个简单的树类:

public class SOTree {
    private final Set<SOTree> children = new HashSet<>();
    private SOTree parent;

    public SOTree(SOTree parent) {
        this.parent = parent;
    }

    public SOTree(Set<SOTree> children) {
        for (SOTree next : children)
            children.add(next);
    }


    public Set<SOTree> getChildren() {
        return Collections.unmodifiableSet(children);
    }

    public SOTree getParent() {
        return parent;
    }
}

现在,如果要创建这些对象的层次结构,则在构造它的过程中,要么父对象必须存在于当前节点之前,要么子对象必须首先存在。
    SOTree root = new SOTree((SOTree)null);
    Set<SOTree> children = createChildrenSomehow(root);
    //how to add children now?  or children to the children?

要么
    Set<SOTree> children = createChildrenSomehow(null);
    SOTree root = new SOTree(children);
    //how to set parent on children?

在不强制其成为单链接树的情况下,是否有任何聪明的方法来构造这样的树,并且仍然使所有节点完全不可变?

最佳答案

两个想法:

  • 使用某种树工厂。您可以使用可变结构来描述树,然后有一个工厂来组装不可变的树。在内部,工厂可以访问不同节点的字段,因此可以根据需要重新连接内部指针,但是生成的树将是不可变的。
  • 围绕可变树构建不可变的树包装。也就是说,让树构造使用可变节点,然后构造一个包装器类,该包装器类随后提供树的不可变 View 。这类似于(1),但没有显式工厂。

  • 希望这可以帮助!

    10-07 13:47