It seems like people are concerned about creating Iterators being slow, but people want to have the use of Iterators because it’s easier to have bug-free code.
Why not have both? I see a way it can be done, but it would make it a bad idea to use the java.util interfaces because iteration would be changed.
The idea is basically to save iterators after using them so that no object creation need to be done. You could do something like:
BagIterator bagIterator = bag.iterator();
//a bunch of code that uses bagIterator, resetting it each time with a "BagIterator.reset" method (which would have to be written)
There is, however, a problem with that. If the Bag is changed to a new Bag, the BagIterator would no longer be valid. So long as this doesn’t happen, it would work (since resetting the iterator is just a matter of changing its index). But there’s a better way.
Store the BagIterator within the Bag.
Create a BagIterator class that does NOT extend Iterator (because that would confuse people). It would add only one method: dispose. Dispose does 2 things: reset the BagIterator and record that the BagIterator is ready for use.
The dispose method works closely with the iterator() method (which probably should be renamed to getBagIterator() or something to avoid confusion with java.util). The dispose method would be as follows:
//in class BagIterator
public void dispose() {
nextIndex = 0;
Bag.this.lastIterator = this;
}
The code for the getBagIterator method would be as follows:
//in class Bag
public BagIterator getBagIterator() {
if(lastIterator == null)
return new BagIterator();
else
return lastIterator;
}
The return type is changed because the calling class needs access to the dispose method. Also, it’s important that lastIterator is stored by dispose, not by getBagIterator. This is so that the iterator is stored only when it’s not in use.
Only one variable “BagIterator lastIterator = null;” would need to be added. It’s just a single variable instead of an array/ArrayList/Bag of BagIterators because storing a whole extra array would be a little over the top, especially if someone never disposes the BagIterators.
This way, the iterator need only be created once unless you’re iterating over the same Bag more than once at the same time. Does anyone see any problems with this?
I haven’t actually tested this. I wanted to see what the response was first because my code was read but not used previously. If I have time later today, I’ll test this myself for performance. If this has decent performance, the get(int) and remove(int) methods could be made private.
Also, it would be possible to create our own faster version of java.util if we wrote a bunch more classes like this. Array (the faster version of ArrayList) could just extend Bag and have a different remove method. There’s already people who have done this (as was mentioned earlier in this topic), so that might not be all that useful.