2011-07-28 156 views
2

好吧,所以我有一個可能有一個父節點(也是一個節點)和一些孩子(也節點)的樹中的節點。java樹節點遞歸泛型

我想要處理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上的Bound不匹配。我試着用下面的嘗試修復它:

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; 

返回的類型是一個列表,而不是我想要的ArrayList。

是我想要做的可能嗎?如果是這樣,也許有人可以告訴我我要去哪裏錯,或者如果不是最好的選擇?

謝謝,裏奇。

+2

「返回的類型是一個列表,而不是我想要的ArrayList」......爲什麼這是一個問題? 'children'被聲明爲'List',而不是'ArrayList'。 –

+0

除了Jim:和'ArrayList'是一個'List',實際上List是如何實現並不重要,只要知道它是List就足夠了 – Tedil

+0

不要使列表的類型爲generic,使用'List '很好。 – starblue

回答

4

正如您發現的那樣,遞歸泛型非常快速變得非常複雜。我看到了兩種選擇。

1:刪除T和讓孩子被宣佈爲List<Node<U>>

2:在聲明節點是抽象,添加一個自參考,並限定一個具體的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); 
    } 

}