Я могу написать вложенный цикл для итерации по элементам вложенного массива, для каждого элегантно скрывает детали обхода на каждом уровне вложенного массива:
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();
}
}
}
Но проблемы с этим подходом:
- Тот факт, что для обхода структуры данных необходим двойной вложенный цикл, до боли очевиден.
- Мне нужно скопировать этот вложенный цикл для каждой функции, которую мне нужно вызвать для внутренних элементов.
- Это нарушает инкапсуляцию метода обхода структуры. Я могу решить реализовать вложенный массив с какой-либо другой структурой и не хочу менять каждую копию вложенных итераций на какой-либо другой метод обхода.
- Структура вложенных циклов for-each наизнанку от того, что необходимо. Вместо того, чтобы иметь требуемый вызов функции внутри гнезд, Итератор должен обрабатывать внутреннюю структуру данных, обнажая каждую запись, обнаруженную во время обхода.
Итак ... как мне изменить это так, чтобы я реализовал Итератор, который мог бы вызывать как:
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.
}
Это оставило бы детали того, как итерация выполняется классу Foo_Iterator.
У меня вопрос "Как мне написать Foo_Iterator, отслеживая состояние вложенных итераторов?"
Я думаю, это выглядело бы примерно так, но мне не хватает фрагментов, которые отслеживают состояние.
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.
}
}
Любые предложения о том, как сделать это "элегантным" способом?
Спасибо.