Suppose you have a collection, and you need to perform an action on each element. That’s not hard to do in any mainstream programming language. What if you need to know the index of each element as you process it? Not hard, but depending on your datastructures, possibly not as straightforward as it first sounds.
I think most people reading this will be most familiar with C-style languages.
Traditionally, there are two types of loop construct: a counted for
loop and
an uncounted while
loop. Java was introduced with these loop constructs:
These work well enough, but there’s no way to actually convey what it is
you’re achieving: you’re looping until a condition is met, rather than
explicitly looping over all the elements of the collection. These particular
examples will also only work when accessing something indexable, and are
sub-optimal for collections (like LinkedList
) which don’t have constant-time
access to their elements. You can use an iterator with a while loop to avoid
these issues, but you still have to manually increment your counter:
Java 1.5 adds an explicit iteration construct, which runs off the Iterable
interface:
This leaves your iteration at the right level of abstraction, but you still have to count your elements. In a language like Python, you’d solve this issue by zipping with an integer sequence:
Java doesn’t have the ability to perform multiple assignments, and a general
zip operator is non-idiomatic as with strong typing we really want to avoid a
generic Pair<?,?>
interface. What we can easily do, though, is wrap our
iterable so that it gives us the right information. Consider this code
snippet:
This code also makes it clear what’s going on: you’re released from having to manually manage your counter, and the count and value are accessible on-demand.
It’s not difficult to implement, either. I’ve arranged my code into four classes, although two would probably suffice. I’m using Java 7, and I’ve also pulled in Guava for some helper classes. Complete code is on GitHub. Starting from the top, most of the code’s interaction with the implementation is through the Counted<T>
interface:
The only other user-visible code is the static function counting()
, which returns our iterable:
I’ve put this in a class with a second overloaded version that converts an Iterator
.
The actual implementation of the CountingIterable
isn’t important for the user of the code, but is quite simple – it’s a fairly minimal wrapper around the Iterable
that’s passed in and another wrapper around that Iterable
’s Iterator
. Here’s the CountingIterable
:
And here’s the CountingIterator
that it uses:
Again, the complete code (including test cases) is on GitHub.
You’ll see that most of the complexity, such as there is, is in the next()
function – up to that point, we’re simply wrapping the existing objects. This allows us to write as little code as possible. If we were creating a number of custom iteration types, we could even abstract out the pattern of wrapping the existing Iterator
into an abstract superclass. That’s probably overkill for most use-cases, but I think that thinking about it is a useful exercise in understanding how to apply the design pattern in more complicated (and possibly more useful) cases.