0

I tried to work this out but couldn't.

I need to implement a class which implements iterator and takes iterator as constructor parameter,

1)Need to return every 2nd hasnext

2)Need to return every 2nd next element

Basically I am trying to make use of given iterator received from constructor, But when i use next element on hasnext I am actually increasing the iterator by one element. so problem comes when i independently access hasNext or next element and does not pass all the test cases. Any solution or idea on this

Template and my expected implementation looks like below:

public class AlternateIterator<T> implements Iterator<T>
public AlternateIterator(Iterator<T> target)

public boolean hasNext() {
        boolean returnvalue = false;
                if(iterator.hasNext()) {
                    iterator.next();
                    returnvalue = iterator.hasNext();
                }
                return returnvalue;

    }

    @Override
    public T next() {
        T object = null;
        if(iterator.hasNext()) {
        object  = iterator.next();
        return object;
        }
        else
            return null;

-- Gone through this link but it creates a new implementation itself while i want to use the given template only:

Can we write our own iterator in Java?

Community
  • 1
  • 1
N.Bhat
  • 3
  • 1
  • 3
  • a for loop and some ((i & 1) == 1) should do it, do you really need some iterator? –  Jul 15 '16 at 18:01
  • you can put some conditional branching inside the loop – kpie Jul 15 '16 at 18:02
  • I don't vote close to not close the question, but there is http://stackoverflow.com/questions/16033711/java-iterating-over-every-two-elements-in-a-list –  Jul 15 '16 at 18:04
  • @RC your link is about for loop, what if i want to achieve this as part of iterator since its part of scenario? and I need to make use of iterator received through constructor.. and I dont have access to original list – N.Bhat Jul 15 '16 at 18:11
  • I count at least one answer with an iterator, but OK.. –  Jul 16 '16 at 09:49

3 Answers3

1

Track whether you've skipped the element from the source iterator or not, like this:

import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;

final class AlternateIterator<T>
  implements Iterator<T>
{

  static <T> Iterable<T> alternate(Iterable<T> original)
  {
    return () -> new AlternateIterator<>(original.iterator());
  }

  private final Iterator<T> source;

  private boolean skipped;

  AlternateIterator(Iterator<T> source)
  {
    this.source = Objects.requireNonNull(source);
  }

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

  @Override
  public T next()
  {
    if (hasNext()) {
      skipped = false;
      return source.next();
    }
    throw new NoSuchElementException();
  }

  @Override
  public void remove()
  {
    source.remove();
  }

}
erickson
  • 265,237
  • 58
  • 395
  • 493
0

Your issue is that hasNext() changes the state of the decorated Iterator. You need a member variable like skipped to track state so that hasNext() won't double-advance and skip two, and your implementation of next() should use this.hasNext(), not iterator.hasNext().

Edit: it'll look something like this:

public class AlternateIterator<T> implements Iterator<T> {
    public AlternateIterator(Iterator<T> target) { ... }

    private volatile boolean skipped = false;

    public boolean hasNext() {
        if (!skipped) {
            skipped = true;
            if (iterator.hasNext()) {
                iterator.next();
            }
        }
        return iterator.hasNext();
    }

    @Override
    public T next() {
        hasNext();
        skipped = false;
        return iterator.next();
    }
}
David Ehrmann
  • 7,366
  • 2
  • 31
  • 40
0

You need to have a boolean member which stores if hasNext has been called since the last call of next. This way you know if you need to call an additional next or not in both methods.

garnulf
  • 366
  • 2
  • 6