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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29961456/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 16:10:40  来源:igfitidea点击:

How to copy an iterator to another one?

javaiterator

提问by Amitsh

I need to iterate over the set of values for each iteration of for loop, but only for first iteration it works fine. Thereafter the itr.hasNext()returns false.

我需要为 for 循环的每次迭代迭代一组值,但只有在第一次迭代时它才能正常工作。此后itr.hasNext()回报false

Iterator<String> itr = getQuestionIterator(File file);

for(Person p : persons)
{
    while(itr.hasNext())
    {
        String question = itr.next();
        ........
        ........
    }
}

This behaviour is clear to me.

这种行为对我来说很清楚。

One solution could be calling getQuestionIterator(File file)method in for loop so for each for loop iteration it gets reinitialized. But this is very inefficient approach as itris independent.

一种解决方案可能是getQuestionIterator(File file)在 for 循环中调用方法,因此对于每个 for 循环迭代,它都会重新初始化。但这是一种非常低效的方法,因为它itr是独立的。

I tried this Iterator<String> temp = itr, but it didn't work also as it holds the reference only.

我试过这个Iterator<String> temp = itr,但它也不起作用,因为它只保存参考。

Is there any way to copy the iterator into another one or any other better approach?

有没有办法将迭代器复制到另一个或任何其他更好的方法中?

回答by isnot2bad

An Iteratoris the smallest possible API to work off data sequentially, hence it abstracts from the underlying data source. As it can only move forwards (next()) without any option to reset or rewind, it is a one-way object that must be thrown away after usage. And due to the limited API it offers, it is not possible to simply "copy" it without knowing the implementation and/or the underlying data source.

AnIterator是按顺序处理数据的最小 API,因此它从底层数据源中抽象出来。由于它只能向前(next())移动而没有任何重置或倒带选项,因此它是一种单向物体,使用后必须扔掉。而且由于它提供的 API 有限,不可能在不知道实现和/或底层数据源的情况下简单地“复制”它。

So there are four ways to handle your problem:

因此,有四种方法可以处理您的问题:

(1) Re-aquire a new iterator from the underlying data source

(1)从底层数据源重新获取一个新的迭代器

Just call getQuestionIterator(File file)every time you need to iterate over the data (again).

getQuestionIterator(File file)每次需要迭代数据时调用(再次)。

  • Advantage: Easy to use, easy to implement. No cache required.
  • Disadvantage: Performance (e.g. file has to be read/parsed again). Underlying data source might have been changed in the meantime.
  • 优点:易于使用,易于实施。不需要缓存。
  • 缺点:性能(例如,必须再次读取/解析文件)。在此期间,基础数据源可能已更改。

(2) Combine all processing code into one single iterating loop

(2) 将所有处理代码合并为一个迭代循环

Instead of...

代替...

while (iterator.hasNext()) { /* first processing step */ }
while (iterator.hasNext()) { /* second processing step */ }
while (iterator.hasNext()) { /* third processing step */ }
...

...combine all steps:

...结合所有步骤:

while (iterator.hasNext()) {
    String question = iterator.next();
    /* first processing step */
    /* second processing step */
    /* third processing step */
    ...
}
  • Advantage: Only one iterator required. No cache required.
  • Disadvantage: Not always possible, e.g. if processing steps have dependencies.
  • 优点:只需要一个迭代器。不需要缓存。
  • 缺点:并非总是可行,例如,如果处理步骤具有依赖性。

(3) Copy all elements into a local cache (Collection)

(3) 将所有元素复制到本地缓存 ( Collection)

Iterate over all items once and put them into a local collection that you can use to aquire an arbitrary number of iterators:

迭代所有项目一次并将它们放入本地集合中,您可以使用它来获取任意数量的迭代器:

// 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
...
  • Advantage: Simple to implement, fast, once all data is in the cache.
  • Disadvantage: Additional memory for cache required.
  • 优点:实现简单,速度快,一旦所有数据都在缓存中。
  • 缺点:需要额外的缓存内存。

(4) Modify your data source API to let its implementation handle the problem

(4) 修改你的数据源API,让它的实现来处理问题

Meaning: Change getQuestionIterator(File file)to return an Iterable<String>instead of an Iterator<String>. You can gain an arbitrary number of iterators from an Iterable:

含义:更改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
  • Advantage: The underlying data source knows best how to cache your data. No need to copy your data in case the underlying data source already uses a cache.
  • Disadvantage: It is not always possible to change the API.
  • 优势:底层数据源最了解如何缓存数据。如果底层数据源已经使用缓存,则无需复制数据。
  • 缺点:并不总是可以更改 API。

回答by Mureinik

It depends on the exact contents of your code block, but why not flip the loops? Have the outer loop go over the file, and for each iteration, go over all the Persons:

这取决于代码块的确切内容,但为什么不翻转循环呢?让外部循环遍历文件,并在每次迭代中遍历所有Persons:

Iterator<String> itr = getQuestionIterator(File file);
while(itr.hasNext()) 
{
    String question = itr.next();
    for(Person p : persons)
    {    
        ........
        ........
    }
}

回答by Thilo

You can only iterate an Iterator once.

您只能迭代一个 Iterator 一次。

If you need to "reset" it, and recreating the Iterator is expensive (such as reading from a file), you could copy the data into a temporary Collection (such as an ArrayList). But that requires enough memory to hold everything at once.

如果您需要“重置”它,并且重新创建迭代器的开销很大(例如从文件中读取),您可以将数据复制到临时集合(例如 ArrayList)中。但这需要足够的内存来一次保存所有内容。

Another approach could be (depends on what your program does) to swap the order of loop nesting: Iterate over your iterator just once, and over your Persons in the inner loop (since you already have all those in memory). Obviously, this processes things in a different order which may or may not be easy to accomodate for you.

另一种方法可能是(取决于您的程序做什么)交换循环嵌套的顺序:只迭代一次迭代器,并Person在内循环中迭代s (因为您已经在内存中拥有所有这些)。显然,这会以不同的顺序处理事物,这对您来说可能容易也可能不容易适应。