如何在java中创建树型对象?

如何在java中创建树型对象?,java,tree,nested,Java,Tree,Nested,我一直在想,创建列表中包含列表的对象的最佳实践是什么。假设我有这样一种对象: root = new CarrierTreeNode(null, new CarrierTreeNode[] { new CarrierTreeNode(new CarrierTreeItem("item1"), new CarrierTreeNode[] { new CarrierTreeNode(new Car

我一直在想,创建列表中包含列表的对象的最佳实践是什么。假设我有这样一种对象:

    root = new CarrierTreeNode(null, 
            new CarrierTreeNode[] {
                new CarrierTreeNode(new CarrierTreeItem("item1"), new CarrierTreeNode[] {
                    new CarrierTreeNode(new CarrierTreeItem("item1.1"))
                }),
                new CarrierTreeNode(new CarrierTreeItem("item2"), new CarrierTreeNode[] {
                    new CarrierTreeNode(new CarrierTreeItem("item2.1"))
            })
    });
我想动态地生成它,并动态地访问和修改其中的列表/数组。这个有设计模式吗? 多谢各位


更清楚地说,这里使用的构造函数是这样的:node(item,node[])

您可能想看看复合模式。 简言之,当对象A持有对象A的集合时使用此选项

这种模式/数据结构允许简单的递归行为

有很多信息来源,因此如果这还不够,请简单地转到谷歌获取更多信息,但这里有一个开始:

至于创建部分,在这种情况下,我通常使用工厂或构建器,但具体实现方式有所不同。假设您有一个2d数组if items,并且希望根据该数组创建这些节点

public class NodeBuilder{
    public CarrierTreeNode build(String[][] items){
        CarrierTreeNode node = new CarrierTreeNode(null);
        for(int i = 1; i < items.length; i++){
           CarrierTreeNode nextNode = new CarrierTreeNode(new CarrierTreeItem(items[i][0]));
           node.addNextNode(nextNode);
           for(int j = 1; j < items[i].length; j++)
               nextNode.addNextNode(new CarrierTreeItem(items[i][j]));
        }
        return node;
    }
}
公共类NodeBuilder{
公共CarrierTreeNode生成(字符串[][]项){
CarrierTreeNode节点=新的CarrierTreeNode(null);
对于(int i=1;i
这显然只适用于3层结构。递归方法更可取。您可以创建一个系统,其中build调用build n次,以创建所需的深度。问题是在获取数据时,要使其工作,数据必须已经处于正确的结构中,但必须是字符串。
如果您的字符串是动态生成的,以便构建器能够计算出数据,那么就有可能使其正常工作

我提出这个设计,希望它能帮助你:

  • TreeElement
    iterface:generic树元素类型
  • Item
    类,该类实现了
    treeeElement
    iterface:因此它可以是 树节点的键或树节点的
  • 节点
    类,该类还实现了
    树元素
    接口,因此它可以 可以是基节点或键的值
这是实现:

interface TreeElement {

    enum ElementType {
        NODE, ITEM
    };

    public TreeElement getElement(Item item);

    public Node addElement(Item item, TreeElement element);

    public ElementType getType();

}

class Item implements TreeElement {

    String name;

    public Item(String name) {
        super();
        this.name = name;
    }

    @Override
    public TreeElement getElement(Item item) {
        return null;
    }

    @Override
    public ElementType getType() {
        return ElementType.ITEM;
    }

    @Override
    public Node addElement(Item item, TreeElement element) {
        return null;
    }

    @Override
    public String toString() {
        return "Item [" + name + "]";
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Item other = (Item) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

}

class Node implements TreeElement {

    Map<Item, TreeElement> map;

    {
        map = new HashMap<>();
    }

    @Override
    public TreeElement getElement(Item item) {
        return map.get(item);
    }

    @Override
    public ElementType getType() {
        return ElementType.NODE;
    }

    public Node addElement(Item item, TreeElement element) {
        this.map.put(item, element);
        return this;
    }

    @Override
    public String toString() {
        return "Node " + map + " ";
    }

}
Node node = new Node();
Item item = new Item("Item 1");
node.addElement(item, new Node().addElement(new Item("Level 1"), new Item("Item 1")));

System.out.println(node);
//Print : Node {Item [Item 1]=Node {Item [Level 1]=Item [Item 1]} } 

TreeElement element = node.getElement(item);

if (element.getType().equals(ElementType.NODE)) {
    element.addElement(new Item("Level 2"), new Node().addElement(new Item("Item 2.1"), new Item("Item 2.2")));
}

System.out.println(node);
//Print : Node {Item [Item 1]=Node {Item [Level 1]=Item [Item 1], Item [Level 2]=Node {Item [Item 2.1]=Item [Item 2.2]} } } 

重要提示:
equals()
hashcode()
对于示例的行为至关重要,尤其是
equals()
。它们在
映射
集合中用于确定集合是否包含给定元素。

最简单的树节点实现必须包含一个用于存储数据和自己子级列表的字段

public class Node<T> {

    private T data;
    private List<Node> list = new LinkedList<>();

    public Node(){}

    public Node(T data){
        this.data = data;
    }

    public List<Node> getChildList() {
        return list;
    }

    public void setData(T data) {
        this.data = data;
    }

    public T getData() {
        return data;
    }
}
公共类节点{
私有T数据;
私有列表=新的LinkedList();
公共节点(){}
公共节点(T数据){
这个数据=数据;
}
公共列表getChildList(){
退货清单;
}
公共无效设置数据(T数据){
这个数据=数据;
}
公共T getData(){
返回数据;
}
}
此类已准备好构建简单的树结构:

Node<String> root = new Node<String>("Stark");
root.getChildList().add(new Node<String>("Benjen"));

Node<String> eddard = new Node<String>("Eddard");
root.getChildList().add(eddard);
eddard.getChildList().add(new Node<String>("Arya"));
节点根=新节点(“斯塔克”);
root.getChildList().add(新节点(“Benjen”);
节点eddard=新节点(“eddard”);
root.getChildList().add(eddard);
添加(新节点(“Arya”);

这个实现是最简单的,但当然不是最好的。经典的树节点提供有关父节点和同级节点、内部递归搜索方法、循环引用控制和许多其他内容的信息(描述非常详细)。

几乎是dup,但OP询问的是创建树,而不是结构本身。看起来很不一样。