迭代器检索第一个值并将其放回到同一个迭代器上

时间:2012-08-17 19:29:14

标签: java collections iterator

我有以下场景:我有一个现有的迭代器Iterator<String> it,我迭代它的头部(比如前k个元素,它们是标记元素,即它们以'*'开头)。知道标记元素结束的唯一方法是注意第(k + 1)个元素没有被标记。

问题在于,如果我这样做,迭代器it将不会在下一次调用next()时为我提供第一个值。

我想将此迭代器传递给方法,因为它是唯一的参数,我想避免更改其符号和实现。我知道我可以这样做:

   public void methodAcceptingIterator(Iterator<String> it) //current signature

   //change it to 

  public void methodAcceptingIterator(String firstElement, Iterator<String> it)

但这看起来像一个workarround / hack降低了代码的优雅和通用性,所以我不想这样做。

我有什么想法可以解决这个问题吗?

4 个答案:

答案 0 :(得分:3)

你可以使用Guava的PeekingIterator(链接包含一个静态方法的javadoc,给定一个Iterator,将返回一个包装PeekingIterator)。这包括一个方法T peek(),它可以向您展示下一个元素,但不会向前推进。

答案 1 :(得分:1)

解决方案是创建自己的Iterator实现,该实现存储firstElement并使用现有迭代器作为底层迭代器来委托其余元素的请求。

类似的东西:

  public class IteratorMissingFirst<E> implements Iterator<E>{

private Iterator<E> underlyingIterator;
private E firstElement;
private boolean firstElOffered;

public IteratorMissingFirst(E firstElement, Iterator<E> it){
    //initialize all the instance vars
}

public boolean hasNext(){
    if(!firstElOffered && firstElement != null){
            return true;
    }
    else{
        return underlyingIterator.hasNext();
    }
}

public E next(){
    if(!firstElOffered){
        firstElOffered = true;
        return firstElement;
    }
    else return underlyingIterator.next();
}

public void remove(){

}
}

答案 2 :(得分:0)

为什么不让methodAcceptingIterator存储它从变量中的迭代器中获取的第一个元素?或者 - 在紧要关头 - 只需将Iterator的内容复制到方法开头的ArrayList中;现在你可以随心所欲地重新访问元素。

答案 3 :(得分:0)

使用Guava,您可以使用Iterables类中的一些方法以更简单的方式实现Razvan的解决方案:

Iterators.concat(Iterators.singletonIterator(firstElement), it)

这为你提供了一个类似于IteratorMissingFirst的迭代器,如果你需要查看前面的多个元素,它很容易扩展(但是它创建了两个对象而不是一个)。