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;
}
}
1 Answer 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...
6 Comments
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.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();
MyLinkedListshould not implementIterator, it should instead implementIterable? And onlyMyLinkedListIterator<E>should implementIterator<E>. See an example here of how implementing iterator could work: gist.github.com/jnwhiteh/68d095c630dfcaddffd1