我有以下场景:我有一个现有的迭代器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降低了代码的优雅和通用性,所以我不想这样做。
我有什么想法可以解决这个问题吗?
答案 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
的迭代器,如果你需要查看前面的多个元素,它很容易扩展(但是它创建了两个对象而不是一个)。