我需要为 for 循环的每次迭代迭代一组值,但仅在第一次迭代时它工作正常。此后itr.hasNext()
返回 false
.
Iterator<String> itr = getQuestionIterator(File file);
for(Person p : persons)
{
while(itr.hasNext())
{
String question = itr.next();
........
........
}
}
我很清楚这种行为。
一种解决方案可能是调用 getQuestionIterator(File file)
for 循环中的方法,因此对于每个 for 循环迭代,它都会重新初始化。但这是非常低效的方法 itr
是独立的。
我试过 Iterator<String> temp = itr
,但它也不起作用,因为它仅包含引用。
有没有办法将迭代器复制到另一个或任何其他更好的方法中?
最佳答案
安Iterator
是按顺序处理数据的最小 API,因此它从底层数据源中抽象出来。由于它只能向前移动( next()
)而没有任何重置或倒带选项,因此它是一种单向对象,使用后必须丢弃。而且由于它提供的 API 有限,在不知道实现和/或底层数据源的情况下,不可能简单地“复制”它。
所以有四种方法可以解决您的问题:
(1) 从底层数据源重新获取一个新的迭代器
只需调用 getQuestionIterator(File file)
每次您需要迭代数据时(再次)。
- 优点:易于使用,易于实现。无需缓存。
- 缺点:性能(例如,必须再次读取/解析文件)。与此同时,基础数据源可能已更改。
(2) 将所有处理代码合并到一个迭代循环中
而不是...
iterator = /* get new iterator */
while (iterator.hasNext()) {
String question = iterator.next();
/* first processing step */
}
iterator = /* get new iterator */
while (iterator.hasNext()) {
String question = iterator.next();
/* second processing step */
}
iterator = /* get new iterator */
while (iterator.hasNext()) {
String question = iterator.next();
/* third processing step */
}
...
...结合所有步骤:
iterator = /* get new iterator */
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。
关于java - 如何将一个迭代器复制到另一个?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29961456/