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

时间:2015-10-30 13:50:18

标签: java iterator deque

当通过双向链表调用我的迭代器时,我得到一个空指针异常。空指针异常发生在主要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());
}

有人可以告诉我为什么我会在那时获得空指针异常吗?

3 个答案:

答案 0 :(得分:2)

因为Integer包装器类型可以为空并且在队列中有一个空Integer,然后您尝试将其转换为int primitive type ...

尝试进行条件检查,验证元素是否为空,如下所示:

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

答案 1 :(得分:1)

通过查看循环的终止条件开始:

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

这意味着它上次运行时会返回null,因为它只检查当前元素而不是下一个元素是非空的。

所以你的代码变成这样:

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

int的投射是抛出异常的原因。如果你看一下the rules for how unboxing works,就可以找出原因:

  

如果r是Integer类型的引用,则取消装箱转换将r转换为r.intValue()

所以你的代码变得类似于

((Integer)null).intValue();

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

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

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

答案 2 :(得分:1)

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

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

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

为了安全起见,保留了对null的检查。这可能没有必要。