为什么我为myIt = new MyIterator <e>(开始)?</e>获得堆栈溢出

时间:2012-03-12 16:28:51

标签: java

这是我的代码......

 package calendar;

    import java.util.*;

    /**
     * This class represents a simple implementation of a sorted singly-linked list.
     * Elements added to the list are inserted in sorted order based on an specified
     * Comparator object.
     * <br><br>
     * 
     * This class relies on two classes: MyIterator and MyListNode. We have implemented
     * the MyListNode class for you, but you are responsible for the implementation
     * of the MyIterator class.  Notice these are inner classes defined within the 
     * MySortedLinkedList class.  As a result they may access each other's fields even
     * if they are private.  You are required to use the MyListNode class to implement
     * the nodes of your linked list.
     * <br><br>
     * 
     * Feel free to add any methods to the MySortedLinkedList class you consider are 
     * necessary to implement your project.  <b>However, keep in mind that there are two 
     * methods you are required to implement: an add method returning void (adds an element 
     * to the list keeping the list sorted) and a remove method returning void (removes 
     * any element(s) from the list that are equal to the parameter).</b>  
     * 
     * The JUnit public tests provide an example of using the MySortedLinkedList class.
     * <br><br>
     * 
     * You may not use the Java API LinkedList or ArrayList classes during the implementation
     * of the MySortedLinkedList class.
     *  
     * @author Dept of Computer Science, UMCP
     */

    public class MySortedLinkedList<T> implements Iterable<T> {
        private final Comparator<T> comparator; 
        MyListNode<T> head;
        public int counter = 0;
        /**
         * Creates an empty list that is associated with the specified comparator.
         * @param comparator
         */
        public MySortedLinkedList(Comparator<T> comparator) {
            //throw new UnsupportedOperationException("You must implement this method.");
            head = null;
            this.comparator = comparator;
        }

        /**
         * This class represents a linked list node. 
         * You should not modify this class. 
         * 
         * Because MyListNode is an inner class of MySortedLinkedList,
         * methods in MySortedLinkedList may access fields of MyListNode
         * directly even though they are private.
         * 
         * You may use the default constructor for MyListNode, which
         * initializes both val and next to null.
         * 
         * @param <V>
         */
        private class MyListNode<V> {
            private V val;
            private MyListNode<V> next;
        }



        /**
         * Inserts the specified element at the correct position in the sorted list.
         */
        public void add(T element) {
            MyListNode<T> n = new MyListNode<T>();
            n.val = element;
            n.next = head;
            head = n;

        }

        /**
         * Returns the element at the specified position in this list.
         */
        public T get(int index) {
            //throw new UnsupportedOperationException("You must implement this method.");
            int place = 1;
            MyListNode x = head;
            if(x==null){
                return null;
            }
            while(place<index){
                x=x.next;
            }
            return (T) x.val;
        }

        /**
         * Removes any elements matching given element
         */
        public void remove(T v) { 
            //throw new UnsupportedOperationException("You must implement this method.");
            MyListNode prev = null, curr = head;
            while (curr != null) {
                if (curr.val.equals(v)) {
                    if (curr == head)
                        head = head.next;
                    else{
                        prev.next = curr.next;
                        prev = curr;
                        curr = curr.next;
                    }

                } else {
                    prev = curr;
                    curr = curr.next;
                }
            }
        } 

        public int size() {
            //throw new UnsupportedOperationException("You must implement this method.");
            MyListNode x = head;
            if(x==null){
                return 0;
            }
            while(x.next!= null){
                counter = counter + 1;
                x = x.next;
            }
            return counter;
        }

        public boolean isEmpty() {
            return head==null;
        }

        /**
         * Returns an iterator over the elements in this list (in proper sequence).  
         * @return iterator over the list
         */
        public Iterator<T> iterator() {
            MyIterator<T> something = new MyIterator<T>(head);
            return something;
        }

        /**
         * This class implements an iterator over the list.
         * You must implement this class. 
         * @param <E>
         */
        private class MyIterator<E> implements Iterator<E> {
            //private int counter1 = size();
            //@SuppressWarnings("unchecked")
            MyListNode<E> newHead = (MyListNode<E>) head;
            private Iterator<E> myIt;

            /**
             * Defines an iterator based on the start node provided.
             * @param start
             */
            private MyIterator(MyListNode<E> start) {
                //throw new UnsupportedOperationException("You must implement this method.");
                myIt = new MyIterator<E>(start);
            }

            /**
             * Returns true if there is another element available
             * @return true if there is another element and false otherwise
             */
            public boolean hasNext() {
                //throw new UnsupportedOperationException("You must implement this method.");
                if(head==null){
                    throw new NoSuchElementException();
                }else{
                    if(myIt.hasNext()||counter>1){
                        return true;
                    }else{
                        return false;
                    }
                }
            }

            /**
             * Returns the next element
             * @return next element
             */
            public E next() {
                //throw new UnsupportedOperationException("You must implement this method.");
                if(hasNext()){
                    newHead = newHead.next;
                    return (E) newHead;
                }
                return null;
            }

            /**
             * Removes an element from the list.  You do not need to implement this method.
             */
            public void remove() {
                throw new UnsupportedOperationException("You do NOT need to implement this method");
            }
        }
    }

错误来自私有MyIterator构造函数中的myIt = new MyIterator<E>(start);。我不知道为什么这会导致堆栈溢出。有任何想法吗?所有部分都有评论说明每种方法的目标是什么。几天前,我刚刚得到一个NullPointerException,但是我改变了一些东西,现在得到一个StackOverflow,错误重复在我说的那条线上。

错误来自此测试:

public void testListEmpty() {
        MySortedLinkedList<Activity> myList = new MySortedLinkedList<Activity>(new ActivityComparator());
        Iterator<Activity> iterator = myList.iterator();
        assertTrue(iterator.hasNext() == false);
    }

1 个答案:

答案 0 :(得分:8)

private MyIterator(MyListNode<E> start) {
       //throw new UnsupportedOperationException("You must implement this method.");
       myIt = new MyIterator<E>(start);
}

以递归方式创建自身的新实例的构造函数当然永远不会干净地终止,并且会很快超出堆或堆栈。

为什么您认为MyIterator需要由另一个MyIterator支持?为什么不使用this代替myIt

也许你对构造函数的作用感到困惑。使用new运算符进行任何自定义初始化时,将调用构造函数。它不需要自己创建实例。

另见

Java Tutorials - Providing Constructors for your Classes

修改

如果您想使用MyIterator初始化start,则只需为start创建一个字段:

private final MyListNode<E> start;

private MyIterator(MyListNode<E> start) {
       this.start = start;
}

然后,您可以在start的其他方法中使用MyIterator