为什么我的迭代器中出现空指针异常?
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
的检查。应该没必要吧。
在双向链表上调用我的迭代器时,出现空指针异常。 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
的检查。应该没必要吧。