java树节点递归泛型

时间:2011-07-28 19:06:14

标签: java generics recursion tree

好的,我在树中有一个Node,它可能有一个父节点(也是一个节点)和一些子节点(也是节点)。

我想用Java的泛型做的是允许传入子节点将存储的List类型以及Node将保存的数据。所以我编写了下面的编译器似乎很满意的类。

public class Node<T extends List<Node<T, U>>, U>
{
    public Node<T, U> parent;
    public T children;
    public U data;

    private Class<T> tClass;

    public Node(Class<T> tClass) throws InstantiationException, IllegalAccessException
    {
        this.tClass = tClass;
        this.children = this.tClass.newInstance();
    }
}

问题出在我尝试初始化Node时。

Node<ArrayList, NodeData> node = new Node(ArrayList.class);

由于ArrayList上的绑定不匹配,编译器会抱怨。我尝试通过以下尝试来修复它:

Node<ArrayList<Node>, NodeData> node = new Node(ArrayList.class);
Node<ArrayList<Node<ArrayList, NodeData>>, NodeData> node = new Node(ArrayList.class);
Node<ArrayList<Node<ArrayList<Node>, NodeData>>, NodeData> node = new Node(ArrayList.class);
Node<ArrayList<Node<ArrayList<Node<ArrayList, NodeData>, NodeData>>, NodeData> node = new Node(ArrayList.class);

正如你所看到的,这将永远存在,我知道我可以用

来解决这个问题
public class Node<T extends List<Node>, U>
{
    public Node<T, U> parent;
    public T children;
    public U data;

    private Class<T> tClass;

    public Node(Class<T> tClass) throws InstantiationException, IllegalAccessException
    {
        this.tClass = tClass;
        this.children = this.tClass.newInstance();
    }
}

允许我使用:

Node<ArrayList<Node>, NodeData> node = new Node(ArrayList.class);

然而,当我这样做时:

node.children.get(0).children;

返回的类型是List,而不是我想要的ArrayList。

我正在尝试做什么?如果是这样,或许有人可以告诉我哪里出错了,或者不知道什么是最好的选择?

谢谢,Richy。

1 个答案:

答案 0 :(得分:4)

正如您所发现的,递归泛型变得非常复杂。我看到了两个选项。

1:删除T并让孩子被宣布为List<Node<U>>

2:声明Node为abstract,添加自引用,并定义具体的ArrayList节点引用。

abstract class Node<N extends  Node<N, T, U>, T extends List<N>, U>
{
    public Node<N, T, U> parent;
    public T children;
    public U data;

    private Class<T> tClass;

    public Node(Class<T> tClass) throws InstantiationException, IllegalAccessException
    {
        this.tClass = tClass;
        this.children = this.tClass.newInstance();
    }
    {
        Node<ALNode<Integer>, ArrayList<ALNode<Integer>>, Integer> node = new ALNode<Integer>();
        ALNode<Integer> node2 = new ALNode<Integer>();
    }
}

class ALNode<U> extends Node<ALNode<U>, ArrayList<ALNode<U>>, U> {

    public ALNode() throws InstantiationException,
            IllegalAccessException {
        super((Class) ArrayList.class);
    }

}