迭代器是可以顺序排除数据的最小可能的API,因此它从底层数据源中抽象出来。因为它只能向前移动(next()),没有任何选项来重置或倒带,它是一个单向对象,在使用后必须抛弃。并且由于它提供的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 cache = new ArrayList<>();
while (iterator.hasNext()) cache.add(iterator.next());
// now you can get as many iterators from cache as required:
Iterator iter = cache.iterator();
// use iter
iter = cache.iterator(); // once more
// use iter
...
优点:一旦所有数据都在缓存中,就能实现,快速实现。
>缺点:需要额外的缓存内存。
(4)修改你的数据源API,使其实现处理问题
含义:更改getQuestionIterator(文件文件)以返回Iterable< String>而不是迭代器< String>。您可以从Iterable获得任意数量的迭代器:
Iterable iterable = getQuestionIterator(File file);
Iterator iter = iterable.iterator();
// use iter
iter = iterable.iterator(); // once more
// use iter
>优势:底层数据源最了解如何缓存数据。无需复制数据,以防底层数据源已经使用缓存。>缺点:并不总是可以更改API。