All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nl.vpro.util.LazyIterator Maven / Gradle / Ivy

There is a newer version: 5.3.1
Show newest version
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();
        }

    }
}