рекурсивные дженерики узла дерева Java - PullRequest
2 голосов
/ 28 июля 2011

Хорошо, поэтому у меня есть узел в дереве, у которого потенциально есть родитель (также узел) и некоторые дочерние элементы (также узлы).

То, что я хотел сделать с обобщениями Java, - это разрешить передачу типа List, в котором будут храниться дочерние Nodes, а также данных, которые будет содержать 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<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, что я и хотел.

Вот чтоЯ пытаюсь сделать возможным?Если это так, возможно, кто-то может показать мне, где я иду не так, или если нет, то какая лучшая альтернатива?

Спасибо, Ричи.

1 Ответ

4 голосов
/ 29 июля 2011

Как вы обнаружили, рекурсивные генерики очень быстро становятся очень сложными.Я вижу два варианта для вас.

1: Удалите T и позвольте детям объявить List<Node<U>>

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);
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...