简体   繁体   English

如何实现跳转迭代器

[英]How to implement a jump iterator

Implement next() and hasNext() of a jump iterator, the constructor was passed with another iterator. 实现跳转迭代器的next()和hasNext(),该构造函数与另一个迭代器一起传递。 The next() function will return iterator.next().next() next()函数将返回iterator.next()。next()

I have implemented below code, it doesn't look elegant at all. 我已经实现了下面的代码,看起来一点也不优雅。 And for list {1, 9, 8, 7, 8, 2, 5}, it will only output 9, 7, 2. Any clue to do it in a better way? 对于列表{1、9、8、7、8、2、5},它只会输出9、7、2。有什么线索可以更好地做到这一点?

Basically this jump iterator is trying to iterator each element with one distance, for example, for 1,2,3,4,5, it will return 1,3,5 基本上,此跳转迭代器会尝试以一个距离迭代每个元素,例如,对于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();
    }
}

It seems to me that your problem is in the function 'hasNext' 在我看来,您的问题出在“ hasNext”函数中

Why do you override it? 为什么要覆盖它? What behaviour do you want to obtain? 您想获得什么行为?

When it.hasNext() returns true you consume a value you shouldn't be consuming, due to the use of it.next() right there. 当it.hasNext()返回true时,由于使用了it.next(),因此您将消耗一个不应该使用的值。

Those method implementations are currently assuming that the program always interlaces calls to hasNext and next , which may bring some issues in the long run. 这些方法的实现当前假设程序总是隔行调用hasNextnext ,从长远来看可能会带来一些问题。

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

Here is a way around the problem. 这是解决问题的一种方法。 In short, I'm keeping track of whether the next value was already checked, which in that case I have already skipped one value. 简而言之,我一直在跟踪是否已检查下一个值,在这种情况下,我已经跳过了一个值。

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

Other than that, the jump iterator works if the intended goal is to "skip once and take the next" each time an element is retrieved. 除此之外,如果预期的目标是每次检索元素时“跳过一次并采取下一个”,则跳转迭代器也可以工作。 Under this logic, using the iterator on the sequence [1,2,3,4] would give you [2,4] . 在这种逻辑下,对序列[1,2,3,4]使用迭代器将为您提供[2,4] If you want to have [1,3] instead (as in, not skipping the first value), just tweak the implementation as shown above. 如果要改为使用[1,3] (例如,不跳过第一个值),则只需调整实现即可,如上所示。

I'd make it something like 我会做类似

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;
  }
}

This will not skip the first element. 不会跳过第一个元素。 If you want to do that, then you need the lazy skipping policy described by E_net4. 如果要这样做,则需要E_net4描述的惰性跳过策略。 I'd just factor it out: 我只是把它排除在外:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM