如何实现跳转迭代器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何实现跳转迭代器相关的知识,希望对你有一定的参考价值。

实现了跳转迭代器的next()和hasNext(),构造函数与另一个迭代器一起传递。 next()函数将返回iterator.next()。next()

我已经实现了下面的代码,它看起来并不优雅。对于列表{1,9,8,7,8,2,5},它只会输出9,7,2。任何线索都可以更好地完成它吗?

基本上这个跳转迭代器试图用一个距离迭代每个元素,例如1,2,3,4,5,它将返回1,3,5

public class JumpIterator implements Iterator<Integer> {
    private Iterator<Integer> it;

    public JumpIterator(List<Integer> list){
        it = list.iterator();
    }

    @Override
    public boolean hasNext() {
        if(!it.hasNext()){
            return false;
        }else{
            it.next();
            return it.hasNext();
        }
    }

    @Override
    public Integer next() {
        return it.next();
    }
}
答案

在我看来你的问题是在函数'hasNext'

为什么要覆盖它?你想要获得什么样的行为?

当it.hasNext()返回true时,你会消耗一个你不应该消耗的值,因为在那里使用it.next()。

另一答案

那些方法实现目前假设程序总是交错调用hasNextnext,从长远来看可能会带来一些问题。

JumpIterator jit = ...;
jit.hasNext();
jit.haxNext(); // skipped a relevant value
jit.next();
jit.next(); // obtained two adjacent values

这是解决问题的方法。简而言之,我正在跟踪是否已经检查了下一个值,在这种情况下,我已经跳过了一个值。

public class JumpIterator implements Iterator<Integer> {
    private Iterator<Integer> it;
    private boolean skipped;

    public JumpIterator(List<Integer> list){
        it = list.iterator();
        skipped = false; 
        // if you want to take the first value from the stream,
        // change skipped to true
    }

    @Override
    public boolean hasNext() {
        if (it.hasNext() && !skipped) {
            it.next();
            skipped = true;
        }
        return it.hasNext();
    }

    @Override
    public Integer next() {
        if (!skipped) {
            it.next();
        }
        skipped = false;
        return it.next();
    }
}

除此之外,如果预期的目标是每次检索元素时“跳过一次并取下一个”,则跳迭代器可以工作。在这个逻辑下,使用序列[1,2,3,4]上的迭代器会给你[2,4]。如果你想改为使用[1,3](例如,不跳过第一个值),只需调整实现,如上所示。

另一答案

我会做的就像

public class JumpIterator implements Iterator<Integer> {
  private Iterator<Integer> it;

  public JumpIterator(List<Integer> list){
    this.it = list.iterator();
  }

  @Override
  public boolean hasNext() {
    //hasNext should be idempotent (should not modify the state)
    return it.hasNext();
  }

  @Override
  public Integer next() {
    //If the user didn't check hasNext()
    // NoSuchElementException might be thrown,
    // which is interface-compliant, so we just don't care
    Integer nNext = it.next();

    //Now we must skip the next value
    if (it.hasNext()) it.next();
    return nNext;
  }
}

这不会跳过第一个元素。如果您想这样做,那么您需要E_net4描述的延迟跳过策略。我只考虑一下:

public class JumpIterator implements Iterator<Integer> {
  private Iterator<Integer> it;
  private boolean bMustSkip;

  public JumpIterator(List<Integer> list){
    this.it = list.iterator();
    this.bMustSkip = true;
  }

  private Iterator<Integer> myIterator() {
    if (bMustSkip && it.hasNext()) {
      it.next(); //Skipped
    }
    bMustSkip = false;
    return it;
  }  

  @Override
  public boolean hasNext() {
    //hasNext should be idempotent (should not modify the state)
    return myIterator().hasNext();
  }

  @Override
  public Integer next() {
    //If the user didn't check hasNext()
    // NoSuchElementException might be thrown,
    // which is interface-compliant, so we just don't care
    Integer nNext = myIterator().next();
    bMustSkip = true;
    return nNext;
  }
}
另一答案
public class JumpIterator implements Iterator<Integer> {
  Iterator<Integer> iterator;

  public JumpIterator(Iterator<Integer> iterator) {
    this.iterator = iterator;
  }

  @Override
  public boolean hasNext() {
    return iterator.hasNext();
  }

  @Override
  public Integer next() {
    int res = iterator.next();
    if (iterator.hasNext()) {
        iterator.next();
    }
    return res;
  }

  @Override
  public void remove() {
  }
}

以上是关于如何实现跳转迭代器的主要内容,如果未能解决你的问题,请参考以下文章

c++ 迭代器问题

如何在自定义类中隐藏迭代器和容器实现(无增强)

如何在 C++ 中为 GLSL 片段着色器实现 iGlobalTime?

如何从特征实现中返回HashMap的键上的迭代器?

如何实现随机迭代器?

使用迭代器和向量的插入排序实现