【问题标题】:java tree node recursive genericsjava树节点递归泛型
【发布时间】:2011-07-28 19:06:14
【问题描述】:

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

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

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<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。

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

谢谢,里奇。

【问题讨论】:

  • "返回的类型是一个 List,而不是我想要的 ArrayList"... 为什么这是个问题? children 被声明为 List,而不是 ArrayList
  • 除了Jim: 和ArrayListList 之外,List 实际是如何实现的并不重要,知道它是一个List 就足够了
  • 不要将列表的类型设为泛型,使用List&lt;E&gt; 即可。

标签: java generics recursion tree


【解决方案1】:

正如您所发现的,递归泛型很快就会变得非常复杂。我看到你有两个选择。

1:删除 T 并让孩子被声明为List&lt;Node&lt;U&gt;&gt;

2:将Node声明为抽象,添加自引用,定义具体的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);
    }

}

【讨论】:

    猜你喜欢
    • 2018-12-31
    • 2017-09-26
    • 2018-06-22
    • 1970-01-01
    • 1970-01-01
    • 2014-07-12
    • 1970-01-01
    • 2018-06-06
    • 1970-01-01
    相关资源
    最近更新 更多