Lets say we have an Iterator:
Iterator i;
And two Java methods:
static X f(Iterator i)
static Y g(Iterator i)
They both process through an iterator and produce a result, say "sum", "product", or something else.
Let say the results of these calls for a given i is:
x == f(i)
y == g(i)
And lets say we have another class:
class Pair<X,Y>
{
public X x;
public Y y;
}
I want to write a method:
static Pair<X,Y> h(Iterator i)
So that:
h(i) == Pair<X,Y>(x,y);
How can I write h without modifying or rewriting f or g? The issue is that I may not be able to copy the iterator (it could be an input stream for example), so it seems like me that both f and g have to use the iterator in "parallel". I'd rather not put the entire contents of the iterator into a list, and it may not be possible, as if I'm streaming a large source I might not have enough memory. I don't require the solution have multiple threads however, and would prefer a simpler approach if possible.
This is impossible to do with just the iterator you have. You'll need a quite elaborate scheme where akin to *nix's tee command, just for Java iterators: an object which contains your initial iterator and consumes it as needed, and can be requested to produce one or more "output" iterators. Inside you could be using a queue to store the unconsumed elements.
If you don't want multithreading, then it is simple to realize on theoretical grounds that you will absolutely have to cache the entire produce of the initial iterator. This is because both your iterator-consuming methods are based on the "pull" approach and will insist on consuming the entire sequence before returning.
BTW in Clojure the project lamina does something very similar, just not with Java iterators, but with a concept it calls "channels".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With