java - 如何将一个迭代器复制到另一个?

标签 java iterator

我需要为 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/

相关文章:

java - 我正在尝试用 Java 制作 GUI。我创建了框架,但面板没有显示。怎么了?

java - 不同级别的跑法难度

java - 如何从java中的任何网页下载图像

java - 从字符串中解析日期/时间?

c++ - 带有映射迭代器的错误访问内存

python - 返回给定字典键的下一个键,python 3.6+

java - 在一个应用程序中哪个应该是单例? MongoClient 或 MongoDatabase 或 MongoCollection?

c++ - boost 是否提供 make_zip_range?

javascript - for循环中的jquery迭代器

c++ - 遍历容器的最佳方式