Reputation: 3
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?
Upvotes: 0
Views: 3556
Reputation: 7576
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();
}
}
Upvotes: 0
Reputation: 269677
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();
}
}
Upvotes: 1
Reputation: 366
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.
Upvotes: 0