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

net.digitalid.utility.functional.iterables.InfiniteIterable Maven / Gradle / Ivy

The newest version!
package net.digitalid.utility.functional.iterables;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import net.digitalid.utility.annotations.generics.Specifiable;
import net.digitalid.utility.annotations.generics.Unspecifiable;
import net.digitalid.utility.annotations.method.Pure;
import net.digitalid.utility.annotations.ownership.Captured;
import net.digitalid.utility.functional.failable.FailablePredicate;
import net.digitalid.utility.functional.failable.FailableProducer;
import net.digitalid.utility.functional.failable.FailableUnaryFunction;
import net.digitalid.utility.functional.failable.FailableUnaryOperator;
import net.digitalid.utility.functional.interfaces.Producer;
import net.digitalid.utility.functional.iterators.FilteringIterator;
import net.digitalid.utility.functional.iterators.FlatteningIterator;
import net.digitalid.utility.functional.iterators.GeneratingIterator;
import net.digitalid.utility.functional.iterators.IteratingIterator;
import net.digitalid.utility.functional.iterators.MappingIterator;
import net.digitalid.utility.functional.iterators.PruningIterator;
import net.digitalid.utility.functional.iterators.RepeatingIterator;
import net.digitalid.utility.functional.iterators.ZippingIterator;
import net.digitalid.utility.tuples.Pair;
import net.digitalid.utility.validation.annotations.math.NonNegative;
import net.digitalid.utility.validation.annotations.math.Positive;
import net.digitalid.utility.validation.annotations.type.Functional;
import net.digitalid.utility.validation.annotations.type.ReadOnly;

/**
 * This interface extends the functional iterable interface to model infinite iterables.
 */
@ReadOnly
@Functional
public interface InfiniteIterable<@Specifiable ELEMENT> extends FunctionalIterable {
    
    /* -------------------------------------------------- Constructors -------------------------------------------------- */
    
    /**
     * Returns a new infinite iterable that repeats the given element infinitely.
     */
    @Pure
    public static <@Specifiable ELEMENT> @Nonnull InfiniteIterable repeat(@Captured ELEMENT element) {
        return () -> RepeatingIterator.with(element);
    }
    
    /**
     * Returns a new infinite iterable that iterates over the sequence produced by the given operator from the given first element.
     */
    @Pure
    public static <@Specifiable ELEMENT> @Nonnull InfiniteIterable iterate(@Captured ELEMENT firstElement, @Nonnull FailableUnaryOperator unaryOperator) {
        return () -> IteratingIterator.with(firstElement, unaryOperator);
    }
    
    /**
     * Returns a new infinite iterable that generates an infinite number of elements with the producer produced by the given producer.
     * All producers produced by the given producer should produce the same sequence of elements, otherwise operations like
     * {@link #get(int)} are no longer side-effect free and calling them repeatedly leads to unexpected results.
     */
    @Pure
    public static <@Specifiable ELEMENT> @Nonnull InfiniteIterable generate(@Captured @Nonnull Producer> producer) {
        return () -> GeneratingIterator.with(producer.produce());
    }
    
    /* -------------------------------------------------- Size -------------------------------------------------- */
    
    @Pure
    @Override
    public default boolean isEmpty() {
        return false;
    }
    
    @Pure
    @Override
    public default @NonNegative int size(@Positive int limit) {
        if (limit <= 0) { throw new IndexOutOfBoundsException("The limit has to be positive but was " + limit + "."); }
        
        return limit;
    }
    
    /* -------------------------------------------------- Filtering -------------------------------------------------- */
    
    @Pure
    @Override
    public default @Nonnull InfiniteIterable filter(@Nonnull FailablePredicate predicate) {
        return () -> FilteringIterator.with(iterator(), predicate);
    }
    
    @Pure
    @Override
    public default @Nonnull InfiniteIterable filterNot(@Nonnull FailablePredicate predicate) {
        return filter(predicate.negate());
    }
    
    @Pure
    @Override
    public default @Nonnull InfiniteIterable filterNulls() {
        return filter(element -> element != null);
    }
    
    /* -------------------------------------------------- Mapping -------------------------------------------------- */
    
    @Pure
    @Override
    public default <@Specifiable TYPE> @Nonnull InfiniteIterable map(@Nonnull FailableUnaryFunction function) {
        return () -> MappingIterator.with(iterator(), function);
    }
    
    /* -------------------------------------------------- Instance -------------------------------------------------- */
    
    @Pure
    @Override
    public default <@Specifiable TYPE> @Nonnull InfiniteIterable instanceOf(@Nonnull Class type) {
        return filter(type::isInstance).map(type::cast);
    }
    
    /* -------------------------------------------------- Pruning -------------------------------------------------- */
    
    @Pure
    @Override
    public default @Nonnull InfiniteIterable skip(@Positive int number) {
        return () -> PruningIterator.with(iterator(), number, Integer.MAX_VALUE);
    }
    
    /* -------------------------------------------------- Zipping -------------------------------------------------- */
    
    @Pure
    @Override
    public default <@Specifiable TYPE> @Nonnull InfiniteIterable<@Nonnull Pair> zipShortest(@Nonnull InfiniteIterable iterable) {
        return () -> ZippingIterator.with(iterator(), iterable.iterator(), true);
    }
    
    @Pure
    @Override
    public default <@Unspecifiable TYPE> @Nonnull InfiniteIterable<@Nonnull Pair> zipLongest(@Nonnull FiniteIterable iterable) {
        return () -> ZippingIterator.with(iterator(), iterable.iterator(), false);
    }
    
    /* -------------------------------------------------- Flattening -------------------------------------------------- */
    
    @Pure
    @Override
    public default <@Specifiable TYPE> @Nonnull InfiniteIterable flatten(@Positive int level) {
        return () -> FlatteningIterator.with(iterator(), level);
    }
    
    @Pure
    @Override
    public default <@Specifiable TYPE> @Nonnull InfiniteIterable flattenOne() {
        return flatten(1);
    }
    
    @Pure
    @Override
    public default <@Specifiable TYPE> @Nonnull InfiniteIterable flattenAll() {
        return flatten(Integer.MAX_VALUE);
    }
    
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy