如何实现跳转迭代器

时间:2015-01-27 15:43:03

标签: java iterator

实现跳转迭代器的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();
    }
}

4 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

这些方法实现目前假设程序总是交错调用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](如同,而不是跳过第一个值),只需调整实现,如上所示。

答案 2 :(得分:0)

我做了类似

的事情
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;
  }
}

答案 3 :(得分:0)

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