NPE в методах MyLinkedList

У меня возникли проблемы с NPE в классе MyLinkedList, который расширяет AbstractList. Я начинаю с этих конструкторов:

Конструктор для закрытого класса Node:

public Node(T nodeData, Node<T> nodePrev, Node<T> nodeNext)
    {
        this.data = nodeData;
        this.prev = nodePrev;
        this.next = nodeNext;
    }

Конструктор класса MyLinkedList.

MyLinkedList()
{
    this.head = new Node<T>(null, null, null); 
    this.tail = new Node<T>(null, null, null);
    this.size = 0;
}

MyLinkedList(Node<T> head, Node<T> tail, int size)
{
    this.head = head;
    this.tail = tail;
    this.size = size;
}

и здесь я пытаюсь вернуть узел по индексу с помощью этого метода:

private Node<T> getNth(int index)
{
    Node<T> temp;
    if(index < 0 || index > size)
        throw new IndexOutOfBoundsException();

    if(index < this.size() / 2)
    {
        temp = this.head;
        for(int i = 0; i < index; i++)
        {
            temp = temp.getNext();
        }
    }
    else
    {
        temp = this.tail;
        for(int i = this.size(); i > index; i--)
        {
            temp = temp.getPrev();
        }
    }
    return temp;
}

Я думаю, что основная проблема связана с инициализацией головы и хвоста как null, но я не уверен, что это проблема, и если да, то как ее исправить. Есть ли лучший способ инициализировать эти узлы, чтобы избежать NPE?


person user1547050    schedule 07.10.2012    source источник
comment
Очень просто: 1) посмотрите на трассировку стека (и настройте обработчик исключений и получите трассировку стека, если у вас его нет), 2) посмотрите на строку, дающую исключение нулевого указателя, и 3) выясните, где вы не удалось инициализировать рассматриваемую переменную. Если это сложное выражение, то разбейте его на отдельные строки и получите новую трассировку. ИМХО... PS: Что вы делаете с глобальным размером, вместо того, чтобы просто использовать текущий размер контейнера()?   -  person paulsm4    schedule 07.10.2012
comment
index > size следует сделать index >= size, потому что вы начинаете индексацию с zero   -  person user1406062    schedule 07.10.2012
comment
@ HussainAl-Mutawa На самом деле все в порядке. Он начинает итерацию с уменьшением индекса с size и останавливается на index + 1 вместо того, чтобы начинать с size - 1 и останавливаться на index.   -  person Fritz    schedule 07.10.2012
comment
было бы трудно судить без включенной трассировки стека   -  person user1406062    schedule 07.10.2012


Ответы (1)


Вы инициализируете как голову, так и хвост списка следующим образом:

MyLinkedList()
{
    this.head = new Node<T>(null, null, null); 
    this.tail = new Node<T>(null, null, null);
    this.size = 0;
}

Кажется, это основной источник ваших NPE, потому что ваша итерация не выполняет никаких проверок. В частности, ваш метод потерпит неудачу в граничных условиях (поскольку вы уже проверяете длину, прежде чем даже пытаться выполнить итерацию).

Добавив некоторые проверки, вы можете избежать этих исключений:

private Node<T> getNth(int index)
{
    Node<T> temp = null; //Always try to initialize your variables if you're going
                         //to return them.
    if(index < 0 || index > size)
        throw new IndexOutOfBoundsException();

    if(index < this.size() / 2)
    {
        temp = this.head;
        for(int i = 0; i < index; i++)
        {
            if(temp.getNext() != null)
                 temp = temp.getNext();
            else
                 break;//Break the iteration if there is not a next node
        }
    }
    else
    {
        temp = this.tail;
        for(int i = this.size(); i > index; i--)
        {
            if(temp.getPrev() != null)
                temp = temp.getPrev();
            else
                break;
        }
    }
    return temp;
}

Вы можете генерировать какое-то исключение вместо того, чтобы прерывать итерации, если хотите.

person Fritz    schedule 07.10.2012