0

I am having a problem with Iterators. I am writing a custom linked list as using an iterator to be able to traverse the list.

The iterator looks like this:

public class NodeIterator implements Iterator<Node> {
private Node current = head;
private Node lastReturned = head;

public boolean hasNext() {
    return lastReturned.getLink() != null;
}

public Node next() {
    lastReturned = current;
    current = current.getLink();
    return lastReturned;
}

public void remove() {
    removeNode(lastReturned);
    lastReturned = null;
}
}

I'm still in the early stages so I'm testing the data structures from the console by populating the nodes with this method.

private static void MethodToPopulateNodes() {
MyObject o = new MyObject();
String[] responses = new String[prompts.length];
scanner = new Scanner(System.in);

boolean done = false;
String s = null;

while (!done) {
    int i = 0;
    for (String prompt : prompts) {
        System.out.println(prompt);
        s = scanner.nextLine();
        if (s.equalsIgnoreCase("stop")) {
            done = true;
            break;
    } else {
        responses[i] = s;
    }
        i++;
    }
    if (done) {
        break;
    }
        o = new MyObject(responses);
        myNode.add(c);
}
}

When I try to use the iterator when there is only one Node, it doesn't do anything. No errors or anything. However, if I have multiple nodes, this foreach works flawlessly.

public static void main(String[] args) {
myNode = new Node();

methodToPopulateLinkedList();

for (Node node : myNode) {
        //toString is overridden for my object
    System.out.println(node.getData().toString());
}

}

UPDATE: I edited the iterator to return hasNext() == true on the first iteration:

public class NodeIterator implements Iterator<Node> {
private boolean done = false;
private Node current = head;
private Node lastReturned = head;

public boolean hasNext() {
    if (head == tail && head != null && !done) {
    done = true;
    return true;
    }
    return lastReturned.getLink() != null;
}

public Node next() {
    lastReturned = current;
    current = current.getLink();
    return lastReturned;
}

public void remove() {
    removeNode(lastReturned);
    lastReturned = null;
}
}

I feel like that is super janky but it works. It seems like Java calls hasNext() first before calling next so I have to treat the special case differently.

|123

hasNext() == true
next() == 1

1|23

hasNext() == true
next() == 2

12|3

Where | equals the cursor. Is that accurate? Is there a better way to solve this?

1 Answer 1

2

If there's just one Node, it would have the special case of its ->next being null. Before the loop, try printing out the first node, I think your loop might be looking one ahead.

Sign up to request clarification or add additional context in comments.

5 Comments

Hmmm...I thought about that. The problem is that the first node is printing when the number of elements > 1. If I primed the foreach, I'd get two of the first node.
ok, lets do this then. Remove the loop and try to print node + node.next + ... a three node array.
also in the current code.. what does getData returrn if nothing got allocated to it after creating a new node?
getData is the datum in the node - the actual MyObject object. I'll try removing the loop and just step through the iterator.
I removed the foreach to print out the objects and used the iterator. It still doesn't work for a single node and behaves correctly with > 1.

Your Answer

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.