为什么我的迭代器中出现空指针异常?

Why am I getting a null pointer exception in my iterator?

在双向链表上调用我的迭代器时,出现空指针异常。 main中出现空指针异常,第assertEquals(i, (int) it.next());

     /***************************
      * nested class DequeIterator
      ***************************/
     private class DequeIterator implements Iterator<E>
      {
        // instance data member of ListIterator
        private Node current;

        // constructors for ListIterator
        public DequeIterator()
        {
          current = first; // head in the enclosing list
        }

        public boolean hasNext()
        {
          return current != null;
        }

        public E next()
        {
          if (hasNext() == false){ throw new NoSuchElementException();}
          else {
          E ret = current.item;
          current = current.next;
          return ret;
          }
        }

public void addLast(E item) {

        if (item.equals(null)) { throw new NullPointerException(); }

        else {

        Node node = new Node(item, null);
        Node ptr = last;

        ptr.prev.next = node;
        node.next = ptr;
        node.prev = ptr.prev;
        ptr.prev = node;    
        N++;

        }
    }

public static void main(String[] args) {

        Deque<Integer> lst = new Deque<Integer>(); // empty list


        for(int i = 1; i <= 5; i++) {
              lst.addLast(i);
            }
        assertEquals(5, lst.size());
        Iterator<Integer> it = lst.iterator();
        int i = 1;
        while(it.hasNext()) {
          assertEquals(i, (int) it.next());
          i++;
        }
        assertEquals(6, i);
        assertEquals(5, lst.size());
}

谁能告诉我为什么此时出现空指针异常?

因为 Integer 包装器类型可以为 null,并且在您的队列中有一个 null Integer that you then try to cast as int primitive type ...

尝试进行条件检查以验证元素不为 null,如下所示:

while(it.hasNext()) {
          Integer e = it.next();
          if(e != null)
            assertEquals(i, (int)e );
          i++;
        }

首先查看循环的终止条件:

public boolean hasNext(){
    return current != null;
}

这意味着它最后一次运行时,它将 return null,因为它只检查当前元素而不是下一个元素是否为非空。

所以你的代码变成这样:

Integer it_next = null;
assertEquals(i, (int)it_next);

而对 int 的强制转换就是抛出异常的原因。如果你看一下the rules for how unboxing works,你就会明白为什么:

If r is a reference of type Integer, then unboxing conversion converts r into r.intValue()

所以你的代码变得类似于

((Integer)null).intValue();

这是对空值的方法调用,导致异常。

据推测,如果 next 值为 null,您想要的修复方法是在 hasNext 中不 return true。像这样:

public boolean hasNext(){
    return current != null && current.next != null;
}

鉴于您发布的代码不完整,双端队列的末尾似乎有一个名为 last 的标记,它的 item 很可能是 null

更正您的迭代器以检查 hasNext() 中的 last:

public boolean hasNext()
{
    return current != last && current != null;
}

为了安全起见,已保留对 null 的检查。应该没必要吧。