How to Implement an Iterating Adapter

Iterator
is one of the fundamental Java
interfaces,
introduced in Java 1.2. It is supposed
to be very simple; however, in my experience, many Java developers don’t understand
how to implement a custom one, which should iterate a stream of data
coming from some other source. In other words, it becomes an adapter of
another source of data, in the form of an iterator. I hope this example will help.

Let’s say we have an object of this class:

final class Data {
byte[] read();
}

When we call read(), it returns a new array of bytes that were retrieved
from somewhere. If there is nothing to retrieve, the array will be empty. Now,
we want to create an adapter that would consume the bytes and let
us iterate them:

There is no way to make it
thread-safe because the iterating process
is outside the scope of the iterator. Even if we declare our methods
as synchronized, this won’t guarantee that two threads won’t conflict
when they both call hasNext() and next(). So don’t bother with it and
just document the iterator as not thread-safe, then let its users
synchronize one level higher when necessary.