Deque实现中的空指针异常

时间:2014-04-01 05:17:13

标签: java deque

我正在学习Java,并实现Deque数据结构。这是Node类:

import java.util.*;

public class Deque<Item> implements Iterable<Item> {
    private Node sentinel;

    private class Node {
        Item item;
        Node next;
        Node previous;
        Node(Item value) {
            item = value;
            next = this;
            previous = this;
        }
    }

    public Deque(Item item)                           // construct an empty deque
    {
        Node sentinel = new Node(item);
    }

    public boolean isEmpty()                 // is the deque empty?
    {
        return (size() == 0);
    }
    public int size()                        // return the number of items on the deque
    {
        System.out.println("size");
        if (sentinel.next == sentinel) {
            System.out.println("empty");}
        return 0;

//        }
//        int count = 0;
//        Node temp = sentinel;
//        while (temp != sentinel)
//        {
//            count += 1;
//            temp = temp.next;
//        }
//        return count;
    }
    public void addFirst(Item item)          // insert the item at the front
    {
        if (item == null) {
            throw new java.util.NoSuchElementException();
        }
        Node a = new Node(item);
        if (isEmpty())
        {
            System.out.println("Hello world");
            sentinel.next = a;
            a.previous = sentinel;
        }
        else
        {
            sentinel.next.previous = a;
            sentinel.next = a;
            a.previous = sentinel;
        }
    }
    public void addLast(Item item)           // insert the item at the end
    {
        if (item == null)
            throw new java.util.NoSuchElementException();
        Node a = new Node(item);
        sentinel.previous = a;
        a.next = sentinel;
    }
    public Item removeFirst()                // delete and return the item at the front
    {
        if (isEmpty())
            throw new UnsupportedOperationException();
        Item value = sentinel.next.item;
        sentinel.next = sentinel.next.next;
        sentinel.next.previous = sentinel;
        return value;
    }
    public Item removeLast()                 // delete and return the item at the end
    {
        if (isEmpty())
            throw new UnsupportedOperationException();
        Item value = sentinel.previous.item;
        sentinel.previous = sentinel.previous.previous;
        sentinel.previous.next = sentinel;
        return value;
    }
    public Iterator<Item> iterator()         // return an iterator over items in order from front to end
    {
        return new DequeueIterator();
    }

    private class DequeueIterator implements Iterator<Item>
    {
        private Node current = sentinel;
        public boolean hasNext() {
            return current != null;
        }
        public void remove() {}
        public Item next() {
            Item value = current.item;
            current = current.next;
            return value;
        }

    }
    public static void main(String[] args)   // unit testing
    {
        System.out.println(Thread.currentThread().getStackTrace());
        Deque<Integer> d = new Deque<Integer>(0);
        System.out.println(d.isEmpty());
                System.out.println(Thread.currentThread().getStackTrace());
//        d.addFirst(10);

//        System.out.println(d.size());
        // System.out.println(d.removeLast());
    }
}

然后在检查Deque的大小时如下:

public class Deque<Item> implements Iterable<Item> {
    public Deque()                           // construct an empty deque
    {
        Node sentinel = new Node(null);
        if (sentinel.next == sentinel)
            System.out.println("empty");
    }
}

编译器错误是NullPointerException。是由于Node(null)的初始化?如果是,我如何输入通用项的零值?

堆栈跟踪:

java.lang.NullPointerException
    at Deque.size(Deque.java:29)
    at Deque.isEmpty(Deque.java:24)
    at Deque.main(Deque.java:111)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)

第29行是:

    if (sentinel.next == sentinel)

2 个答案:

答案 0 :(得分:5)

您正在声明一个名为sentinel的局部变量并指定它而不是使用实例字段并进行分配。

public Deque(Item item)                           // construct an empty deque
{
    Node sentinel = new Node(item);
}

应该是

public Deque(Item item)                           // construct an empty deque
{
    this.sentinel = new Node(item);
}

否则实例变量sentinel仍为null,并在您尝试取消引用时导致NullPointerException

public int size()                        // return the number of items on the deque
{
    System.out.println("size");
    if (sentinel.next == sentinel) { // here
        System.out.println("empty");
    }
    return 0;
}

答案 1 :(得分:0)

如果在以下行中出现NullPointerException:

if (sentinel.next == sentinel)

那么唯一的原因可能是sentinel为空。这是因为在Deque的构造函数中,您正在创建一个名为sentinel的新变量,而不是使用类中的变量。