迭代器跑出了Bounds

时间:2018-06-04 20:27:09

标签: java list nullpointerexception iterator

我需要为List类实现自己的Iterator,它的功能类似于Stack,并实现了java.lang.Iterable。 List类中实现的Iterator方法应返回Iterator。

 @Override
public Iterator<E> iterator() {

    return new Iterator<>() {

        private MyEntry<E> it = begin;

        @Override
        public boolean hasNext() {

            if(pos.next != null) {
                return true;
            }
            else {
                return false;
            }
            }

        @Override
        public E next() {
            if (!hasNext()) {
                reset();
            }
            else {
                it = it.next;
            }
            return it.o;
        }

        @Override
        public void remove() {

        }
    };
}

List本身就像Stack一样。它有一个开始条目,标记列表的开头。每个条目都包含对下一个条目的引用。通过pos元素,List可以跟踪其位置。 advance()方法允许您通过Entry by Entry传递列表。 elem()方法返回Entry在pos位置保存的Value。 add()方法在List的末尾添加一个Entry。 delete()方法删除pos处的Entry。

import java.util.Iterator;
import java.util.NoSuchElementException;

public class MyList<E> implements Cloneable, java.lang.Iterable {


public MyList() {
    pos = begin = new MyEntry<E>();
}

public boolean empty() {
    return begin.next == null;
}

public boolean endpos() { // true, if end has been reached
    return pos.next == null;
}

public void reset() {
    pos = begin;
}

public void advance() {
    if (endpos()) {
        throw new NoSuchElementException("Already at the end of this List");
    }
    pos = pos.next;
}

public E elem() {
    if (endpos()) {
        throw new NoSuchElementException("Already at the end of this List");
    }
    return pos.next.o;
}


public void add(E x) {
    MyEntry<E> newone = new MyEntry<E>(x, pos.next);

    pos.next = newone;
}


public void delete() {
    if (endpos()) {
        throw new NoSuchElementException("Already at the end of this List");
    }
    pos.next = pos.next.next;
}

列表所持有的Entrys在下一个MyEntry中具有通用值o和引用

    class MyEntry<E>  {

    MyEntry<E> next;
    E o;

    MyEntry() {
        this(null, null);
    }

    MyEntry(E o) {
        this(o, null);
    }

    MyEntry(E o, MyEntry<E> e) {
        this.o = o;
        this.next = e;
    }
}

但是当我用我的测试类MyListTest测试它时,我得到了三个测试字符串,但之后程序在next()方法中抛出NullPointerException返回it.o

import org.junit.Test;
import java.util.*;

public class MyListTest {

 @Test
 public void test() {
     MyList list = new MyList();
     Iterator itr = list.iterator();

    list.add("a");
    list.add("b");
    list.add("c");

    while(itr.hasNext()) {
        Object element = itr.next();
        System.out.println(element + " ");
    }

    iter.remove();

    while(itr.hasNext()) {
        Object element = itr.next();
        System.out.println(element + " ");
    }
}

}

我的问题是为什么迭代器在最后一个条目之后用完了界限以及如何防止它。

1 个答案:

答案 0 :(得分:0)

所以解决方案就是hasNext()方法

        @Override
        public boolean hasNext() {

            if(pos.next != null) {
                return true;
            }
            else {
                return false;
            }
        }

应该是

        @Override
        public boolean hasNext() {

            if(it.next != null) {
                return true;
            }
            else {
                return false;
            }
        }

因为hasNext()和next()都不会干扰pos元素。 迭代器应该保持自己的位置独立于其他类。