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

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

There is a newer version: 5.3.1
Show newest version
package nl.vpro.util;

import java.util.*;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import com.google.common.collect.PeekingIterator;

/**
 * An iterator that is also {@link AutoCloseable}.
 * @author Michiel Meeuwissen
 * @since 1.1
 */
public interface CloseableIterator extends Iterator, AutoCloseable {


    static void closeQuietly(AutoCloseable... closeables) {
        for (AutoCloseable closeable : closeables) {
            try {
                if (closeable != null) {
                    closeable.close();
                }
            } catch (Exception e) {
                // ignore
            }
        }
    }

    /**
     * @since 2.9
     */
    static  CloseableIterator empty() {
        return new CloseableIterator() {
            @Override
            public void close() {
            }
            @Override
            public boolean hasNext() {
                return false;
            }
            @Override
            public T next() {
                throw new NoSuchElementException();
            }
        };
    }

    /**
     * 

Morphs an existing {@link Iterator} into a {@link CloseableIterator}.

* *

* If it is already a {@link CloseableIterator} it will be returned unchanged. * If it implements {@link AutoCloseable} then its {@link AutoCloseable#close()} method will be called. * If not then the {@link #close()} method will do nothing. *

* * @since 2.9 */ @SuppressWarnings({"unchecked", "rawtypes"}) static CloseableIterator of(final Iterator iterator) { if (iterator instanceof CloseableIterator) { return (CloseableIterator) iterator; } else if (iterator instanceof PeekingIterator) { return new WrappedPeekingCloseableIterator<>((PeekingIterator) iterator); } else { return new WrappedCloseableIterator<>(iterator); } } static CloseablePeekingIterator peeking(CloseableIterator wrapped){ return wrapped == null ? null : wrapped.peeking(); } default Stream stream() { return StreamSupport.stream( Spliterators.spliteratorUnknownSize(this, Spliterator.ORDERED), false).onClose(() -> { try { this.close(); } catch (Exception exception) { throw new RuntimeException(exception); } }); } /** * If you need a guava {@link PeekingIterator}, this will make you one. It remains also a {@link CloseableIterator} */ default CloseablePeekingIterator peeking() { return new CloseablePeekingIteratorImpl<>(this); } class WrappedCloseableIterator implements CloseableIterator { protected final Iterator iterator; protected WrappedCloseableIterator(Iterator iterator) { this.iterator = iterator; } @Override public void close() throws Exception { if (iterator instanceof AutoCloseable) { ((AutoCloseable) iterator).close(); } } @Override public boolean hasNext() { return iterator.hasNext(); } @Override public S next() { return iterator.next(); } @Override public void remove() { iterator.remove(); } @Override public String toString() { return "Closeable[" + iterator + "]"; } } class WrappedPeekingCloseableIterator extends WrappedCloseableIterator implements PeekingIterator { protected WrappedPeekingCloseableIterator(PeekingIterator iterator) { super(iterator); } @Override public S peek() { return ((PeekingIterator) iterator).peek(); } } }