views:

62

answers:

3

Is it possible to iterate through a LL in Java using a ListIterator, add objects periodically to the list, and process these items in the list in the order they were added?

Let's say I start with a LL with a single object in it. I process this object, and decide I want to add two additional objects, which I want to further process (like FIFO). Intuitively, I start the process with

while (itr.hasNext()) {
itr.next();
...
itr.add();
}

However, this seems to quickly crumble - add actually adds items BEFORE the index I currently am at, and not after (ListIterator javadoc). This means when I hit the while loop start again, it actually doesn't recognize that stuff was added to the LL, because it actually needs to go BACKWARDS (.hasPrevious() instead of .hasNext()) to find it. But I can't start the LL with .hasPrevious() (i don't think) because the first item in the LL is a .next() item.

How does one cleanly do this? Or am i just being stupid?

A: 

I believe you have to separate adding to the list and iterating through it.

duffymo
@duffymo: from the linked javadoc - "An iterator for lists that allows the programmer to traverse the list in either direction, modify the list during iteration, and obtain the iterator's current position in the list."
hatorade
As per the [Sun Java Tutorials](http://java.sun.com/docs/books/tutorial/collections/interfaces/collection.html#Iterator): "Note that `Iterator.remove` is the *only* safe way to modify a collection during iteration; the behavior is unspecified if the underlying collection is modified in any other way while the iteration is in progress."
Matt Ball
@bears: so did sun write the ListIterator class, or did someone else? if sun wrote it, clearly that statement is false.
hatorade
If you are using a ListIterator, Add is most definitely supported. Have you looked at the list iterator interface recently?
jjnguy
@justin: did you notice that i pasted a link to the javadoc above? also, the question is NOT whether there is an add method. it's why the add method adds stuff behind my current position in the list, making it impossible to continually grow the list i'm searching ***in the same direction that i'm searching***. Instead, it grows the opposite way.
hatorade
@hatorade: That's the way it's defined. I hear that it doesn't meet your expectations, which you find frustrating. However there are other ways to easily accomplish what you want.
Jim Garrison
@hator My comment was directed at the OP.
jjnguy
@Justin Nelson - apparently I haven't reviewed the javadocs lately, but how do you respond to the issues that the OP reports and the conclusion that his requirements can't be met? The actual behavior of the class is the final arbiter, not the javadocs. I think my answer looks more correct than your javadocs citation.
duffymo
@duffymo The class is behaving exactly as its Javadocs describe from what I can tell. And he can accomplish what he wants with the list iterator as well, though there are probably better ways. He seems to basically just be whining that he wants it to work one way but it doesn't, so the class is a failure.
ColinD
@duffy The only problem here is that the Asker wants the iterator to do something it doesn't. The first sentence of your answer is wrong. But the second part may be correct.
jjnguy
Agreed. I've removed the first sentence.
duffymo
+1  A: 

You didn't quote the entire definition in your comment above:

Inserts the specified element into the list (optional operation). The element is inserted immediately before the next element that would be returned by next, if any, and after the next element that would be returned by previous, if any. (If the list contains no elements, the new element becomes the sole element on the list.) The new element is inserted before the implicit cursor: a subsequent call to next would be unaffected, and a subsequent call to previous would return the new element. (This call increases by one the value that would be returned by a call to nextIndex or previousIndex.)

The new item is inserted so that you have to call previous() to get it.

If you have to insert the item at the current iteration point, then you will have to do the management yourself and call previous(), which will involve restructuring the loop somewhat.

If you can add the new items to the end of the list and process them later, use a Queue implementation instead.

Jim Garrison
i guess that's what i'm looking for... it just seems this is a worthless class if i can't add things to my list and search through those, too.
hatorade
actually, i don't think that's what i'm looking for. i did mention that (not in the quote, but in text). as read like that, this class seems useless to me. i'm wondering if i'm interpreting its potential wrong. if it is indeed impossible to do what i want, then fine, but i'm wondering if i'm just not thinking about the iteration process creatively enough.
hatorade
Queue implements Iterable, so you don't have to remove things from a queue, you can still iterate over it. Look at the ConcurrentLinkedQueue class.
Jim Garrison
@jim: i don't think this works either. i checked the javadocs. I can remove the head item, but the only way to "march" down the queue is with the iterator, if i read it correctly, at which point the comment about iterators crashing probably applies... i'm about to give up and just use two queues. i thought this would just be nicer but apparently it's just useless.
hatorade
A: 

If you aren't going to be doing any removing in the loop, you could call previous() once per call to add() at the end of the loop body. This would leave the cursor before the first added item, which would then be returned by next() on the next iteration. I have to say, I feel like there must be a better way of doing this processing though.

ColinD
He'd have to call previous() twice, since the first previous() would actually return the new element and next() would fetch the one after.
Jim Garrison
@colind: like being able to grow the LL in the direction i'm searching? i agree :(
hatorade
@Jim Garrison No, the first `previous()` returns the new element and sets the cursor *before* it such that a subsequent call to `next()` will return the same thing. From the Javadoc: Note that alternating calls to next and previous will return the same element repeatedly.
ColinD
@hatorade Your use case for this class is not typical. Note that if this class worked like you want it to, calling `add()` twice in a row would result in the second element being added *before* the first one, which is counter to how adding to a list is expected to work.
ColinD
@colind: Thanks for the clarification. You are correct, of course :-)
Jim Garrison