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

dev.marksman.collectionviews.ImmutableNonEmptyVector Maven / Gradle / Ivy

There is a newer version: 1.2.3
Show newest version
package dev.marksman.collectionviews;

import com.jnape.palatable.lambda.adt.Maybe;
import com.jnape.palatable.lambda.adt.hlist.Tuple2;
import com.jnape.palatable.lambda.functions.Fn1;
import com.jnape.palatable.lambda.functions.Fn2;
import dev.marksman.enhancediterables.ImmutableNonEmptyFiniteIterable;

import static com.jnape.palatable.lambda.adt.Maybe.just;
import static com.jnape.palatable.lambda.adt.Maybe.nothing;
import static dev.marksman.collectionviews.ConcreteVectorBuilder.concreteVectorBuilder;

/**
 * A {@code Vector} that is guaranteed at compile-time to be non-empty and safe from mutation anywhere.
 * In other words, it owns the sole reference to the underlying collection.
 * 

* In addition to the guarantees of {@link Vector}, {@link NonEmptyVector}, and {@link ImmutableVector}, * provides the following benefits: *

    *
  • {@code ImmutableNonEmptyVector#fmap} always returns a {@code ImmutableNonEmptyVector}.
  • *
  • {@code ImmutableNonEmptyVector#reverse} always returns a {@code ImmutableNonEmptyVector}.
  • *
  • {@code ImmutableNonEmptyVector#zipWithIndex} always returns a {@code ImmutableNonEmptyVector}.
  • *
* * @param the element type */ public interface ImmutableNonEmptyVector extends NonEmptyVector, ImmutableVector, ImmutableNonEmptyFiniteIterable { /** * Returns the cartesian product of this {@code ImmutableNonEmptyVector} with another {@code ImmutableNonEmptyVector}. *

* Does not make copies of any underlying collections. *

* The returned {@link ImmutableNonEmptyVector} will have a size of {@code size()} × {@code other.size()}, * but will allocate no extra memory (aside from a few bytes for housekeeping). * * @param other an {@code ImmutableNonEmptyVector} of any type * @param the type of the other {@code ImmutableNonEmptyVector} * @return a {@code ImmutableNonEmptyVector>} */ default ImmutableNonEmptyVector> cross(ImmutableNonEmptyVector other) { return ImmutableVectors.nonEmptyCross(this, other); } /** * Maps a function over this {@code ImmutableNonEmptyVector}. *

* Returns a new {@link ImmutableNonEmptyVector} of the same size (but possibly a different type). *

* Does not make any copies of underlying collections. *

* This method is stack-safe, so a {@code ImmutableNonEmptyVector} can be mapped as many times as the heap permits. * * @param f a function from {@code A} to {@code B}. * Not null. * This function should be referentially transparent and not perform side-effects. * It may be called zero or more times for each element. * @param The type of the elements contained in the output Vector. * @return an {@code ImmutableNonEmptyVector} of the same size */ @Override default ImmutableNonEmptyVector fmap(Fn1 f) { return ImmutableVectors.nonEmptyMap(f, this); } /** * Returns the init of this {@code ImmutableNonEmptyVector}. *

* The init of a {@link ImmutableNonEmptyVector} is the same {@code Vector} with the last element dropped. * May be empty. *

* Does not make copies of any underlying collections. * * @return an {@code ImmutableVector} */ @Override default ImmutableVector init() { return dropRight(1); } /** * Returns an {@code ImmutableNonEmptyFiniteIterable} of contiguous groups of elements in this {@code ImmutableNonEmptyVector} * that match a predicate pairwise. * * @param predicate the predicate function. * This function should be referentially transparent and not perform side-effects. * It may be called zero or more times for each element. * @return an {@code ImmutableNonEmptyFiniteIterable>} containing the contiguous groups */ @Override default ImmutableNonEmptyFiniteIterable> magnetizeBy(Fn2 predicate) { return ImmutableVectors.nonEmptyMagnetizeBy(predicate, this); } /** * Creates an {@code ImmutableNonEmptyVector} with this {@code ImmutableNonEmptyVector}'s elements in reversed order. *

* Does not make copies of any underlying collections. * * @return an {@code ImmutableNonEmptyVector} */ @Override default ImmutableNonEmptyVector reverse() { return ImmutableVectors.nonEmptyReverse(this); } /** * Returns the tail of this {@code ImmutableNonEmptyVector}. *

* The tail of an {@link ImmutableNonEmptyVector} is the same {@code ImmutableNonEmptyVector} with the first element dropped. * May be empty. *

* Does not make copies of any underlying collections. * * @return an {@code ImmutableVector} */ @Override default ImmutableVector tail() { return drop(1); } /** * Returns an {@code ImmutableNonEmptyVector} containing the same elements as this one. *

* Since this is an {@link ImmutableNonEmptyVector} already, this method simply returns * itself. * * @return itself */ @Override default ImmutableNonEmptyVector toImmutable() { return this; } /** * Attempts to convert this {@code ImmutableVector} to an {@code ImmutableNonEmptyVector}. *

* Since this will always be successful for {@link ImmutableNonEmptyVector}s, * this method always returns itself wrapped in a {@link Maybe#just}. *

* Does not make copies of any underlying collections. * * @return this {@code ImmutableNonEmptyVector} wrapped in a {@link Maybe#just} */ @Override default Maybe> toNonEmpty() { return just(this); } /** * Attempts to convert this {@code ImmutableVector} to a {@code ImmutableNonEmptyVector}. *

* Since this will always be successful for {@link ImmutableNonEmptyVector}s, * this method always returns itself. *

* Does not make copies of any underlying collections. * * @return this {@code ImmutableNonEmptyVector} */ @Override default ImmutableNonEmptyVector toNonEmptyOrThrow() { return this; } /** * Zips together this {@code ImmutableNonEmptyVector} with another {@code ImmutableNonEmptyVector} by applying a zipping function. *

* Applies the function to the successive elements of of each {@code ImmutableNonEmptyVector} until one of them runs out of elements. *

* Does not make copies of any underlying collections. * * @param fn The zipping function. * Not null. * This function should be referentially transparent and not perform side-effects. * It may be called zero or more times for each element. * @param other The other {@code ImmutableNonEmptyVector} * @param The element type of the other {@code ImmutableNonEmptyVector} * @param The element type of the result * @return A {@code ImmutableNonEmptyVector} */ default ImmutableNonEmptyVector zipWith(Fn2 fn, ImmutableNonEmptyVector other) { return ImmutableVectors.nonEmptyZipWith(fn, this, other); } /** * Zips this {@code ImmutableNonEmptyVector} with its indices. *

* Does not make copies of any underlying collections. * * @return a new {@code ImmutableNonEmptyVector} containing pairs consisting of all elements of this {@code ImmutableNonEmptyVector} paired with their index. * Indices start at 0. */ @Override default ImmutableNonEmptyVector> zipWithIndex() { return ImmutableVectors.nonEmptyZipWithIndex(this); } /** * Creates a {@code ImmutableNonEmptyVector} with the given elements. * * @param first the first element * @param more the remaining elements * @param the element type * @return an {@code ImmutableNonEmptyVector} */ @SuppressWarnings("varargs") @SafeVarargs static ImmutableNonEmptyVector of(A first, A... more) { return Vectors.nonEmptyVectorOf(first, more); } /** * Creates a new {@code NonEmptyVectorBuilder}. * * @param first the first element * @param the element type * @return an empty {@link VectorBuilder} */ static NonEmptyVectorBuilder builder(A first) { return concreteVectorBuilder(nothing(), first); } /** * Creates a new {@code NonEmptyVectorBuilder} with an initial capacity hint. * * @param initialCapacity an initial capacity hint. * Must be >= 0. * @param first the first element * @param the element type * @return an empty {@link VectorBuilder} */ static NonEmptyVectorBuilder builder(int initialCapacity, A first) { return concreteVectorBuilder(just(initialCapacity), first); } }