Here is my code….
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");
}
}
}
The error comes at myIt = new MyIterator<E>(start); in the private MyIterator constructor. I have no idea why this is causing a stack overflow. Any ideas? All the sections have comments saying what the goal is for each method. A few days ago I was just getting a NullPointerException, but I changed something and now get a StackOverflow with the error repeating on the line I stated.
The error comes from this test:
public void testListEmpty() {
MySortedLinkedList<Activity> myList = new MySortedLinkedList<Activity>(new ActivityComparator());
Iterator<Activity> iterator = myList.iterator();
assertTrue(iterator.hasNext() == false);
}
A constructor that recursively creates a new instance of itself will of course never cleanly terminate and will quickly overrun either the heap or the stack.
Why do you think
MyIteratorneeds to be backed by anotherMyIterator? Why not just usethisinstead ofmyIt?Perhaps you are confused as to what a constructor does. The constructor is called when you use the
newoperator to do any custom initialization. It doesn’t need to create the instance itself.See also
Java Tutorials – Providing Constructors for your Classes
Edit
If you want to initialize
MyIteratorwithstart, you just need to create a field forstart:Then you can use
startin your other methods ofMyIterator.