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

Java 迭代器检索第一个值并将其放回同一迭代器,java,collections,iterator,Java,Collections,Iterator,我有以下场景:我有一个现有的迭代器迭代器it,我在它的头上迭代(比如前k个元素,它们是标记的元素,即它们以“*”开头)。知道标记的元素已结束的唯一方法是注意到第(k+1)个元素未标记 问题是,如果我这样做,迭代器it在下次调用next()时将不再向我提供第一个值 我想把这个迭代器传递给一个方法,因为它是唯一的参数,我想避免更改它的signarture和它的实现。我知道我可以做到: public void methodAcceptingIterator(Iterator<String&

我有以下场景:我有一个现有的迭代器
迭代器it
,我在它的头上迭代(比如前k个元素,它们是标记的元素,即它们以“*”开头)。知道标记的元素已结束的唯一方法是注意到第(k+1)个元素未标记

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

我想把这个迭代器传递给一个方法,因为它是唯一的参数,我想避免更改它的signarture和它的实现。我知道我可以做到:

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

   //change it to 

  public void methodAcceptingIterator(String firstElement, Iterator<String> it)
public void methodAcceptingIterator(Iterator it)//当前签名
//换成
public void methodAcceptingIterator(String firstElement,Iterator it)
但是这看起来像是一个工作狂/黑客降低了代码的优雅性和通用性,所以我不想这样做


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

解决方案是创建自己的迭代器实现,它存储
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(){

}
}
公共类IteratorMissingFirst实现迭代器{
私有迭代器位于迭代器之下;
私人电子第一要素;
私有布尔型优先提供;
public IteratorMissingFirst(E firstElement,迭代器it){
//初始化所有实例变量
}
公共布尔hasNext(){
如果(!firstElOffered&&firstElement!=null){
返回true;
}
否则{
返回underlineIterator.hasNext();
}
}
公共教育{
如果(!firstElOffered){
firstElOffered=正确;
返回第一个元素;
}
else返回underyingIterator.next();
}
公共空间删除(){
}
}

解决方案是创建自己的迭代器实现,它存储
第一个元素
,并使用现有迭代器作为底层迭代器,将对其余元素的请求委托给

比如:

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

}
}
公共类IteratorMissingFirst实现迭代器{
私有迭代器位于迭代器之下;
私人电子第一要素;
私有布尔型优先提供;
public IteratorMissingFirst(E firstElement,迭代器it){
//初始化所有实例变量
}
公共布尔hasNext(){
如果(!firstElOffered&&firstElement!=null){
返回true;
}
否则{
返回underlineIterator.hasNext();
}
}
公共教育{
如果(!firstElOffered){
firstElOffered=正确;
返回第一个元素;
}
else返回underyingIterator.next();
}
公共空间删除(){
}
}

为什么不让
methodAcceptingIterator
将从迭代器中获取的第一个元素存储在变量中?或者——必要时——只需将
迭代器
的内容复制到方法开头的
数组列表
;现在,您可以随时重新访问元素。

为什么不让
methodAcceptingIterator
将从迭代器中获取的第一个元素存储在变量中?或者——必要时——只需将
迭代器
的内容复制到方法开头的
数组列表
;现在,您可以随时重新访问元素。

您可以使用Guava(链接包含静态方法的javadoc,给定一个
迭代器,它将返回一个包装
PeekingIterator
)。这包括一个方法
T peek()
,它向您显示下一个元素,而不前进到它。

您可以使用Guava的(链接包含静态方法的javadoc,给定一个
迭代器,它将返回一个包装
peek迭代器
)。这包括一个方法
T peek()
,它向您显示下一个元素而不前进。

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

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

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

使用Guava,您可以通过使用
Iterables
类中的一些方法更轻松地实现Razvan的解决方案:

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

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

我不能使用ArrayList,因为这个迭代器有大量的值。它不适合在主内存中。现在还不清楚您想对第一个元素做什么,以及为什么不能将它存储在变量中作为方法的第一步。我当然可以这样做,但这意味着修改methodAcceptingIterator的实现……是的。是的。我无法想象任何解决方案不涉及修改
methodAcceptingIterator
的实现,包括上面建议的其他解决方案。但是它不会改变签名,这大概是你能得到的最好的签名了。我不能使用ArrayList,因为这个迭代器有大量的值。它不适合在主内存中。现在还不清楚您想对第一个元素做什么,以及为什么不能将它存储在变量中作为方法的第一步。我当然可以这样做,但这意味着修改methodAcceptingIterator的实现……是的。是的。我无法想象任何解决方案不涉及修改
methodAcceptingIterator
的实现,包括上面建议的其他解决方案。但是它不会改变签名,这大概是你能得到的最好的。有趣的迭代器!我不知道!这意味着我可以在工作之外使用它