0

我在扩展 AbstractList 的 MyLinkedList 类中遇到了 NPE 的一些问题。我从这些构造函数开始:

私有 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;
}

我认为主要问题与将头部和尾部初始化为空有关,但我不确定这是否是问题,如果是,如何解决。有没有更好的方法来初始化这些节点以避免 NPE?

4

1 回答 1

0

您正在使用以下内容初始化列表的头部和尾部:

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

如果需要,您可以抛出某种异常而不是中断迭代。

于 2012-10-07T05:24:39.933 回答