package de.invesdwin.util.collections.iterable; import java.util.NoSuchElementException; import javax.annotation.concurrent.NotThreadSafe; import de.invesdwin.util.error.FastNoSuchElementException; @NotThreadSafe public abstract class ASkippingIterator<E> implements ICloseableIterator<E> { private final ICloseableIterator<? extends E> delegate; private E cachedReadNext; public ASkippingIterator(final ICloseableIterator<? extends E> delegate) { this.delegate = delegate; } @Override public boolean hasNext() { return readNext() != null; } @Override public E next() { final E readNext = readNext(); cachedReadNext = null; if (readNext == null) { throw new FastNoSuchElementException("ASkippingIterator: readNext is null"); } return readNext; } private E readNext() { if (cachedReadNext != null) { return cachedReadNext; } else { try { while (delegate.hasNext()) { final E next = delegate.next(); if (!skip(next)) { cachedReadNext = next; break; } } //catching nosuchelement might be faster sometimes than checking hasNext(), e.g. for LevelDB } catch (final NoSuchElementException e) { close(); return null; } return cachedReadNext; } } protected abstract boolean skip(E element); @Override public void close() { delegate.close(); } }