链接列表,不断获取NullPointerException

时间:2015-02-08 21:09:08

标签: java linked-list

我正在尝试将Point添加到链接列表中,以便跟踪每个数据条目的频率。每次运行此代码时,它都会给我一个NullPointerException。我不明白为什么,对我而言似乎在它增加频率之后会产生差距,但我似乎无法解决它。

if(firstNode == null)
    {
        addPair = new Pair(aData, 1);
        firstNode = new Node(null, addPair, null);
        lastNode = firstNode;
        currentNode = firstNode;
        numberOfNodes++;
    }
    else
    {
        currentNode=firstNode;
        for(int count = 0; count<numberOfNodes; count++)
            {
                if(currentNode.data.fst().equals(aData))
                {                                  
                    addPair = new Pair(aData,currentNode.data.freq()+1);
                    if(count==0)
                        firstNode= new Node(currentNode,addPair,null);
                    currentNode = new Node(currentNode,addPair,null);
                    break;
                }
                if(count == (numberOfNodes-1) && currentNode.data.fst() !=(aData))
                    {
                            addPair = new Pair(aData,1);
                            Node newNode = new Node(currentNode, addPair, null);
                            currentNode.next = newNode;
                            lastNode = newNode;
                            numberOfNodes++;
                            break;
                        }
                        currentNode = currentNode.next;
                    }

    }

    numberOfEntries++;

     private class Node
{
    private Node previous;
    private Pair data;
    private Node next;

    private Node(Node previousNode, Pair<T,Integer> addPair, Node nextNode)
    {
        previous = previousNode;
        data = addPair;
        next = nextNode;
    }
}       

2 个答案:

答案 0 :(得分:0)

如果您在if(currentNode.data.fst().equals(aData))行接收NPE,则currentNode == nullcurrentNode.data == nullcurrectNode.data.fst() == null。诊断问题的第一件事是找出其中的哪一个。我建议你在这行之前加上以下语句并重新运行代码:

assert currentNode != null;
assert currentNode.data != null;
assert currentNode.data.fst() != null;

除了诊断之外,您还可以通过多种方式使代码更安全。首先,您确实无需使用计数来遍历链表。当next指针为null

时,结束会更安全
for (Node current = firstNode; current != null; current = current.next) {
    if (current.data.equals(aData)) {
        // increment counter
        return;
    }
}

答案 1 :(得分:0)

主要问题在于此行

firstNode= new Node(currentNode,addPair,null);

当您增加第一个节点的频率时,您没有设置下一个Node,因此您只有一个节点的列表,但大小为多个节点。与行类似的问题

currentNode = new Node(currentNode,addPair,null);

所有第一个if声明都是错误的。你破坏了列表中的链接,它应该是这样的

if (currentNode.data.fst().equals(aData)) {
    addPair = new Pair(aData, currentNode.data.freq() + 1);
    // create new node
    Node c = new Node(currentNode.previous, addPair, currentNode.next);
    // set links to new node
    if (currentNode.previous != null) {
        currentNode.previous.next = c;
    }
    if (currentNode.next != null) {
        currentNode.next.previous = c;
    }
    if (count == 0) {
        firstNode = c;
    } 
    break;
} 

为了简化代码并减少可能的错误,我建议在incFrequency()类中编写Pair之类的函数。然后在循环中执行类似这样的操作

if (currentNode.data.fst().equals(aData)) {
    currentNode.data.incFrequency();
    break;
} else if(count == (numberOfNodes-1) && currentNode.data.fst() !=(aData)) {
    // add new node to the end
}

您也可以重写for循环

currentNode = firstNode;
// iterate through list
while (currentNode != null) {
    // process currentNode 
    ...
    // move to the next node
    currentNode = currentNode.next;
}