I can write a nested loop to iterate over the elements of a nested array, the for-each elegantly hides the details of the traversal over each level of the nested array:
Foo[][] dbl_array;
public void do_all() {
// Iterate over both levels of a nested array, invoking "bar" on each inner element.
for (final Foo[] arr_1d : dbl_array) {
for (final Foo el : arr_1d) {
el.bar();
}
}
}
But the problems with this approach are:
So...how do I change this so that I implement an Iterator that I could invoke like:
Foo_Iterator fi = Foo.iterator();
for (final Foo el : fi) { // The Iterator hides the traversal details from the caller.
el.bar(); // The desired function is invoked on each element encountered.
}
This would leave the details of how the iteration is done to the Foo_Iterator class.
My question is "How do I write Foo_Iterator, keeping track of the state of the nested iterators? I think it would look something like the following, but I'm missing the bits that keep track of the state.
class Foo_Iterator extends Whiz implements Iterator {
public Foo_Iterator() {
// Initialize state based on access to the superclass Whiz.
}
public boolean hasNext() {
// Is there an elegant way to save the state of both iterators between each call to hasNext() and next()?
// The "inelegant" way would be to keep track of the inner and out array indices,
// comparing the current index to the array length...
}
public Foo next() {
// Access the "next" in the nested sequence.
}
public void remove() {
// I probably won't implement or need/use this one.
}
}
Any suggestions on how to do this the "elegant" way?
Thanks.
Not sure if this is any more elegant, but you can use iterators too keep track of the state for you (using String
for example purposes):
class FooIterator implements Iterator<String> {
private final Iterator<String[]> outer;
private Iterator<String> inner = null;
public FooIterator(String[][] data) {
outer = Arrays.asList(data).iterator();
nextInner();
}
private void nextInner() {
if (outer.hasNext())
inner = Arrays.asList(outer.next()).iterator();
}
public boolean hasNext() {
return inner != null && inner.hasNext();
}
public String next() {
String next = inner.next();
if (!inner.hasNext())
nextInner();
return next;
}
public void remove() {
// not used
}
}
I actually don't think there's anything wrong with keeping track of the two indices.
Of course, in your code fi
should really be an Iterable
(presumably your super class), which instantiates FooIterator
, which the consumers should never see.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.