0

I am trying to iterate over the MylinkedList using the MyLinkedListIterator class I created. I am expecting it to print out drop, goofy, Donald, Duck, Mouse etc... but the while loop that I wrote is not working properly. I tried debugging by system.out.print(iter.next()) expecting the first element to be printed in the linked list "drop" but instead was returned null.

public class xxx_xxx_xxxx{
 
 public static void main(String[] args) throws Exception {
 
 
 MyLinkedList<String> list = new MyLinkedList<>();
 
 list.add("drop");
 list.add("goofy");
 list.add("Donald");
 list.add("Duck");
 list.add("Mouse");
 list.add("Kangaroo");
 list.add("Koala");
 // initialized list of MyLinkedListIterator
 MyLinkedListIterator<String> iter = new MyLinkedListIterator<String>();
 
 while (iter.hasNext()) {
 System.out.print(iter.next());
 }
 
 }
 
 }
 
 interface MyList<E> {
 
 public void insert(int index, E object) throws Exception;
 
 public void add(E object);
 
 public E get(int index) throws Exception;
 
 public int indexOf(E object);
 
 public int lastIndexOf(E object);
 
 public E remove(int index) throws Exception;
 
 public E set(int index, E object) throws Exception;
 
 public int size();
 
 }
 
 class Node<E> {
 E element;
 Node<E> next;
 
 public Node(E element) {
 this.element = element;
 }
 }
 
 class MyLinkedList<E> implements MyList<E>, Iterator<E> {
 Node<E> head = null;
 Node<E> tail = null;
 int size = 0;
 
 @Override
 public void insert(int index, E object) throws Exception {
 if (index < 0 || index > size - 1)
 throw new Exception("Invalid index.");
 
 Node<E> newNode = new Node<>(object);
 
 Node<E> current = head;
 int counter = 0;
 Node<E> previous = null;
 while (counter < index) {
 previous = current;
 current = current.next;
 counter++;
 }
 
 if (previous != null)
 previous.next = newNode;
 newNode.next = current;
 
 size++;
 
 if (index == 0)
 head = newNode;
 if (index == size - 1)
 tail = newNode;
 
 }
 
 @Override
 public void add(E object) {
 Node<E> newNode = new Node<E>(object);
 
 size++;
 
 if (head == null)
 head = newNode;
 else
 tail.next = newNode;
 tail = newNode;
 
 }
 
 @Override
 public E get(int index) throws Exception {
 if (index < 0 || index > size - 1)
 throw new Exception("Invalid index.");
 
 Node<E> current = head;
 int counter = 0;
 while (counter < index) {
 current = current.next;
 counter++;
 }
 
 return current.element;
 }
 
 @Override
 public int indexOf(E object) {
 Node<E> current = head;
 int index = 0;
 while (current != null) {
 if (object.equals(current.element))
 return index;
 current = current.next;
 index++;
 }
 return -1;
 }
 
 @Override
 public int lastIndexOf(E object) {
 
 int result = -1;
 Node<E> current = head;
 int index = 0;
 while (current != null) {
 if (object.equals(current.element))
 result = index;
 current = current.next;
 index++;
 }
 
 return result;
 }
 
 @Override
 public E remove(int index) throws Exception {
 if (index < 0 || index > size - 1)
 throw new Exception("Invalid index.");
 
 Node<E> current = head;
 int counter = 0;
 Node<E> previous = null;
 while (counter < index) {
 
 previous = current;
 current = current.next;
 counter++;
 }
 
 if (previous != null)
 previous.next = current.next;
 E result = current.element;
 
 size--;
 
 if (index == 0)
 head = current.next;
 if (index == size - 1)
 tail = previous;
 
 return result;
 }
 
 @Override
 public E set(int index, E object) throws Exception {
 if (index < 0 || index > size - 1)
 throw new Exception("Invalid index.");
 
 Node<E> current = head;
 int counter = 0;
 while (counter < index) {
 current = current.next;
 counter++;
 
 }
 
 E result = current.element;
 current.element = object;
 return result;
 
 }
 
 @Override
 public int size() {
 // TODO Auto-generated method stub
 return size;
 }
 
 public Iterator<E> iterator() {
 // TODO Auto-generated method stub
 return new MyLinkedListIterator();
 }
 
 @Override
 public String toString() {
 
 String result = "[";
 Node<E> current = head;
 while (current != null) {
 
 result += current.element;
 if (current.next != null)
 result += ", ";
 
 current = current.next;
 }
 return result + "]";
 }
 
 @Override
 public boolean hasNext() {
 // TODO Auto-generated method stub
 return false;
 }
 
 @Override
 public E next() {
 // TODO Auto-generated method stub
 return null;
 }
 }
 
 //Create the class MyLinkedListIterator<E>, which implements the Iterator<E> interface.
 
 class MyLinkedListIterator<E> implements Iterator<E> {
 
 // MyLinkedListIterator should contain the following data items,
 
 // "list" of type MyLinkedList
 MyLinkedList<E> list = new MyLinkedList<>();
 
 // "currentNode" of type Node<E>, initially set to list.head
 Node<E> currentNode = list.head;
 
 // The hasNext() method should return true as long as currentNode is not null
 
 public boolean hasNext() {
 
 return currentNode != null;
 
 }
 
 // The next() method should return the list's data item at currentNode, and
 // advance currentNode
 
 public E next() {
 
 Node<E> res = list.head;
 currentNode = list.tail;
 return (E) res;
 
 }
 
 }
asked Oct 5, 2021 at 21:45
1
  • There is far too much going on in your code that simply doesn't work. What are you trying to achieve, are you simply making your own implementation of a linked list? If so then in addition to the corrections commented on the answer below, MyLinkedList should not implement Iterator, it should instead implement Iterable? And only MyLinkedListIterator<E> should implement Iterator<E>. See an example here of how implementing iterator could work: gist.github.com/jnwhiteh/68d095c630dfcaddffd1 Commented Oct 6, 2021 at 0:46

1 Answer 1

1

There are several problems with next(). One that you immediately set the currentNode to the very end of the list, which is probably why you are getting null as the second element if I'm guessing correctly.

currentNode = list.tail;

Think about this. You have a linked list. What is the next element after the current one? It is not the tail...

answered Oct 5, 2021 at 22:30
Sign up to request clarification or add additional context in comments.

6 Comments

I apologize if this answer is novice but would it be currentNode.next ?
Yes, the next method should have currentNode = currentNode.next;. also this line is problematic Node<E> res = list.head;, and will cause the next method will ALWAYS return the list.head, instead it should be changed to Node<E> res = currentNode; to return the current node of the iterator.
You're awesome, thank you!
@AndrewAmirzadeh Just note also that this line MyLinkedListIterator<String> iter = new MyLinkedListIterator<String>(); simply creates a new iterator with no list/elements. It is not tied to your list in any way, so it will always return null because you create an internal empty list MyLinkedList<E> list = new MyLinkedList<>(); Instead try MyLinkedListIterator<String> iter = list.iterator();
I kept going through all the fixes and now I'm getting this: Cannot read field "next" because "this.currentNode" is null. Do I need to make a construtor? I thought by default a constructor is made with one blank.
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.