1

我有以下情况:我有一个现有的迭代器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)

但这看起来像是一种降低代码优雅性和通用性的工作方法/hack,所以我不想这样做。

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

4

4 回答 4

3

您可以使用 Guava 的PeekingIterator(链接包含静态方法的 javadoc,给定一个Iterator,将返回一个 wrapping PeekingIterator)。这包括一种方法T peek(),它可以向您显示下一个元素,而无需前进。

于 2012-08-17T19:35:12.520 回答
1

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

就像是:

  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(){

}
}
于 2012-08-17T19:30:32.060 回答
0

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

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

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

于 2012-08-17T20:24:17.787 回答
0

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

于 2012-08-17T19:32:25.687 回答