Reputation: 55
I'm learning to iterate, and have implemented an Iterator on my 'CStickChart' Class using the following private property:
private List<CStick> cStickCollection = new ArrayList<CStick>();
and then implementing the method to return CSticks:
public Iterator<CStick> iterator() {
return this.cStickCollection.iterator();
}
Now when I try and iterate through it, I'm able to do so with the assigned localCStick but calling the next() method on the CStickChart Iterator doesn't do what I expected it to. I expected it to give me the next CStick in my CStickChart (hence when I call the getEPIC I was expecting it to give me the next EPIC along).
// Print the EPIC out of the Array using the iterator
for (CStick localCStick : testCStickChart) {
System.out.println(localCStick.getEPIC());
//The below line doesn't return the next CStick and I'm not sure why
System.out.println("next EPIC is " + testCStickChart.iterator().next().getEPIC());
}
Please could someone explain why this is not the case (it always returns the first EPIC)
Upvotes: 1
Views: 6497
Reputation: 106490
It sounds like you don't want to use the enhanced-for
structure. The reason: an enhanced-for
with an iterable entity will use the iterator provided internally, and will only ever advance forward.
This also means that any calls to a iterator
while inside that loop produce an iterator that starts at the beginning of iteration.
So, with that, you have two options - both of which involve abandoning the enhanced-for
:
for
loop with indexing to advance backwards and forwards with the list, orListIterator
as provided by List
to move backwards and forwards in a very seamless way.Here is an example with using integers - note that every time I advance the iterator I have to move it back to its previous spot so that I don't double-advance it. Also, I have a condition to break out of the loop once we've run out of elements.
List<Integer> integerList = new ArrayList<Integer>() {{
add(1);
add(2);
add(3);
add(4);
add(5);
add(6);
add(7);
add(8);
add(9);
add(10);
}};
for (ListIterator<Integer> iterator = integerList.listIterator(); iterator.hasNext(); ) {
int value = iterator.next();
int nextValue = Integer.MIN_VALUE;
if (iterator.hasNext()) {
nextValue = iterator.next();
// Reset the state of the iterator
iterator.previous();
}
System.out.println("Value = " + value);
if(nextValue != Integer.MIN_VALUE) {
System.out.println("Next value = " + nextValue);
}
}
Upvotes: 1
Reputation: 79
Everytime you call testCStickChart.iterator()
inside of that loop, you create a new iterator object. So each call to next()
is carried out on a new iterator object, returning the first object. What you want to do is to declare a new Iterator<CStick>
just before the loop and use it inside the loop, like so:
Iterator<CStick> it = testCStickChart.iterator();
// Print the EPIC out of the Array using the iterator
for (CStick localCStick : testCStickChart) {
System.out.println(localCStick.getEPIC());
//The below line doesn't return the next CStick and I'm not sure why
System.out.println("next EPIC is " + it.next().getEPIC());
}
Upvotes: 1
Reputation: 201507
Because you are getting the top iterator of cStickCollection
with .iterator()
. I think you wanted to use the same iterator
position as you're at in your loop, and peek
at the next element. You can't do that with a for-each
loop and you also can't do that with an Iterator
in general (because they don't implement a peek
).
Instead, you could use a traditional for
loop on your cStickCollection
like
for (int i = 0, len = cStickCollection.size(); i < len; i++) {
CStick localCStick = cStickCollection.get(i);
System.out.println(localCStick.getEPIC());
if (i + 1 < len) { // <-- check that there is a "next"
System.out.println("next EPIC is "+cStickCollection.get(i+1).getEPIC());
}
}
Upvotes: 0
Reputation: 206926
System.out.println("next EPIC is " + testCStickChart.iterator().next().getEPIC());
This happens because in this line you are getting a new iterator in every iteration of the loop. Each new iterator starts from the beginning of the list again.
Upvotes: 1