Ответ 1
An Iterator
- это наименьший возможный API для последовательной обработки данных, поэтому он абстрагируется от основного источника данных. Поскольку он может двигаться только вперед (next()
) без какой-либо опции для reset или перемотки назад, это односторонний объект, который следует выбросить после использования. И из-за ограниченного API, который он предлагает, невозможно просто "скопировать" его, не зная реализации и/или основного источника данных.
Итак, есть четыре способа решения вашей проблемы:
(1) Перезагрузите новый итератор из основного источника данных
Просто вызовите getQuestionIterator(File file)
каждый раз, когда вам нужно перебирать данные (снова).
- Преимущество: Простота в использовании и простота в использовании. Не требуется кеш.
- Недостаток: производительность (например, файл должен быть снова прочитан/обработан). Между тем исходный источник данных мог быть изменен.
(2) Объедините весь код обработки в один цикл итерации
Вместо...
while (iterator.hasNext()) { /* first processing step */ }
while (iterator.hasNext()) { /* second processing step */ }
while (iterator.hasNext()) { /* third processing step */ }
...
... объединить все шаги:
while (iterator.hasNext()) {
String question = iterator.next();
/* first processing step */
/* second processing step */
/* third processing step */
...
}
- Преимущество: требуется только один итератор. Не требуется кеш.
- Недостаток: Не всегда возможно, например. если этапы обработки имеют зависимости.
(3) Скопируйте все элементы в локальный кеш (Collection
)
Итерации по всем элементам один раз и поместите их в локальную коллекцию, которую вы можете использовать для получения произвольного количества итераторов:
// read everything into a local cache
Collection<String> cache = new ArrayList<>();
while (iterator.hasNext()) cache.add(iterator.next());
// now you can get as many iterators from cache as required:
Iterator<String> iter = cache.iterator();
// use iter
iter = cache.iterator(); // once more
// use iter
...
- Преимущество: просто реализовать, быстро, как только все данные находятся в кеше.
- Недостаток: требуется дополнительная память для кэша.
(4) Измените свой API-интерфейс источника данных, чтобы его реализация справилась с проблемой
Значение: Измените getQuestionIterator(File file)
, чтобы вернуть Iterable<String>
вместо Iterator<String>
. Вы можете получить произвольное количество итераторов из Iterable
:
Iterable<String> iterable = getQuestionIterator(File file);
Iterator<String> iter = iterable.iterator();
// use iter
iter = iterable.iterator(); // once more
// use iter
- Преимущество: базовый источник данных лучше всего знает, как кэшировать ваши данные. Нет необходимости копировать данные, если базовый источник данных уже использует кеш.
- Недостаток: Не всегда возможно изменить API.