Iterable Deque NullPointerException

时间:2015-02-05 21:52:39

标签: java nullpointerexception deque

我正在尝试通过实现双链表格式来创建一个Deque类(可以添加到两端并在两端引用的Stack / Queue)。

import java.util.Iterator;

公共类Deque实现了Iterable {

Node first;
Node last;
int size;

public Deque()
{
    first = null;
    last = null;
    size = 2;

    first.next = last;
    last.prev = first;
}

private class Node
{
    Node next;
    Node prev;
    Item item;
}

private class ListIterator implements Iterator<Item>
{
    private Node current = first;

    public boolean hasNext()
    {
        return current.next != null;
    }
    public Item next()
    {
        Item item = current.item;
        current = current.next;
        return item;
    }
    public void remove()
    {
        /* not supported */
    }
}

public boolean isEmpty()
{
    if(first == null&&last == null)
        return true;
    return false;
}

public int size()
{
    return size;
}

public void addFirst(Item item)
{
    Node oldfirst = first;
    first = new Node();
    first.item = item;
    first.next = oldfirst;
    oldfirst.prev = first;
    size++;
}

public void addLast(Item item)
{
    Node oldlast = last;
    last = new Node();
    last.item = item;
    last.prev = oldlast;
    oldlast.next = last;
    size++;
}

public Item removeFirst()
{
    Item item = first.item;
    first = first.next;
    size--;
    return item;
}

public Item removeLast()
{
    Item item = last.item;
    last = last.next;
    size--;
    return item;
}

@Override
public Iterator<Item> iterator() 
{
    return (new ListIterator());
}

public static void main(String[] args)
{
    Deque<Integer> deque = new Deque<Integer>();
    for(int i=0; i<5; i++)
    {
        deque.addFirst(i);
        deque.addLast(9-i);
    }

    for(Integer i : deque)
    {
        StdOut.println(i);
    }
}

}

当我运行代码时,当它尝试执行first.next = last时,我得到一个NullPointerException;我可以理解为什么,但我不确定如何修复它而不打破列表。有解决方案吗是否可能没有必要使用双向链接格式(即完全删除上一个参考节点)?

3 个答案:

答案 0 :(得分:1)

您的尺码如何从2开始?在您添加0之前,它应为Item

您的初始条件应该是prevnext都是null。添加单个项目时,大小应为1prevnext都应指向该对象。

答案 1 :(得分:1)

当Deque为空时,没有&#34; next&#34;和&#34;之前&#34;。它完全是空的。会有&#34; next&#34;和&#34;之前&#34;只有有数据才会出现。

因此,当您初始化Deque时,不应尝试将prevnext分配给null引用。它们是null的事实表明那里没有任何东西,所以当然之前或之​​后都没有任何东西。

当然,大小应为零。

然后,在addFirstaddLast方法中,您应该处理firstlast为空的情况。在这种情况下,您必须将它们初始化为相同的值,其中nextprev都是null。并将大小设置为1。

如果firstlast中的项目分别为空,则只按您的操作继续(添加项目,更正链接)。

请务必在nullremoveFirst方法中检查removeLast

短版:空列表的情况很特殊。你应该从一个空列表开始。您应该使用addremove方法检查此特殊情况。

答案 2 :(得分:1)

通过避免访问未初始化的变量来避免NullPointerException。

在该特定示例中,请忽略:

first.next = last;
last.prev = first;

在你的构造函数中使用防御性编程,并在访问变量之前检查null是否未初始化。

例如在你的addFirst方法中:

public void addFirst(Item item)
{
    Node oldfirst;
    if (first != null){
        oldfirst = first;
    }

    first = new Node();
    first.item = item;

    if (oldfirst != null){
        first.next = oldfirst;
        oldfirst.prev = first;
    }
    size++;
}

顺便说一下,这是一次学习练习吗?如果没有,Java库确实准备好使用Deques,包括链表: http://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html