nl.vpro.util.LazyIterator Maven / Gradle / Ivy
package nl.vpro.util;
import lombok.Getter;
import java.util.Iterator;
import java.util.Optional;
import java.util.function.Supplier;
import org.checkerframework.checker.nullness.qual.NonNull;
/**
* Wraps a supplier around an iterator. This way you can delay the instantiation of the actual iterator until the first call
* of hasNext() or next().
* @author Michiel Meeuwissen
*/
public class LazyIterator implements CloseableIterator, CountedIterator {
private final Supplier> supplier;
private Iterator iterator;
@Getter
private Long count = 0L;
@lombok.Builder(builderClassName = "Builder")
public LazyIterator(Supplier> supplier) {
this.supplier = supplier;
}
public static LazyIterator of(Supplier> supplier) {
return new LazyIterator<>(supplier);
}
@Override
public boolean hasNext() {
return getSupplied().hasNext();
}
@Override
public T next() {
T n = getSupplied().next();
count++;
return n;
}
private Iterator getSupplied() {
if (iterator == null) {
iterator = supplier.get();
}
return iterator;
}
@Override
public @NonNull Optional getSize() {
getSupplied();
if (iterator instanceof CountedIterator) {
return ((CountedIterator) iterator).getSize();
} else {
return Optional.empty();
}
}
@Override
public void close() throws Exception {
if (iterator != null && iterator instanceof AutoCloseable) {
((AutoCloseable) iterator).close();
}
}
}