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

dev.marksman.collectionviews.ImmutableVector 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.ImmutableFiniteIterable;
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.EmptyVectorBuilder.emptyVectorBuilder;

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

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

    *
  • {@link ImmutableVector#fmap} always returns a {@code ImmutableVector}.
  • *
  • {@link ImmutableVector#take} always returns a {@code ImmutableVector}.
  • *
  • {@link ImmutableVector#drop} always returns a {@code ImmutableVector}.
  • *
  • {@link ImmutableVector#slice} always returns a {@code ImmutableVector}.
  • *
  • {@link ImmutableVector#reverse} always returns a {@code ImmutableVector}.
  • *
  • {@link ImmutableVector#zipWithIndex} always returns a {@code ImmutableVector}.
  • *
  • {@link ImmutableVector#toImmutable} always returns itself.
  • *
* * @param the element type */ public interface ImmutableVector extends Vector, ImmutableFiniteIterable, Immutable { /** * Returns the cartesian product of this {@code ImmutableVector} with another {@code ImmutableVector}. *

* Does not make copies of any underlying collections. *

* The returned {@link ImmutableVector} 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 ImmutableVector} of any type * @param the type of the other {@code ImmutableVector} * @return a {@code ImmutableVector>} */ default ImmutableVector> cross(ImmutableVector other) { return ImmutableVectors.cross(this, other); } /** * Returns a new {@code ImmutableVector} that drops the first {@code count} elements of this {@code ImmutableVector}. *

* Does not make copies of any underlying collections. *

* Use caution when taking a small slice of a huge {@link ImmutableVector} that you no longer need. * The smaller slice will hold onto a reference of the larger one, and will prevent it from being GC'ed. * * @param count the number of elements to drop from this {@code ImmutableVector}. * Must be >= 0. * May exceed size of this {@code ImmutableVector}, in which case, the result will be an * empty {@code ImmutableVector}. * @return an {@code ImmutableVector} */ @Override default ImmutableVector drop(int count) { return ImmutableVectors.drop(count, this); } /** * Returns a new {@code ImmutableVector} that drops all except the last {@code count} elements of this {@code ImmutableVector}. *

* Does not make copies of any underlying collections. *

* Use caution when taking a small slice of a huge {@code Vector} that you no longer need. * The smaller slice will hold onto a reference of the larger one, and will prevent it from being GC'ed. * * @param count the number of elements to drop from the end of this {@code ImmutableVector}. * Must be >= 0. * May exceed size of this {@code ImmutableVector}, in which case, the result will be an * empty {@code ImmutableVector}. * @return a {@code ImmutableVector} */ @Override default ImmutableVector dropRight(int count) { return ImmutableVectors.dropRight(count, this); } /** * Returns a new {@code ImmutableVector} that drops longest prefix of elements of this {@code ImmutableVector} that satisfy a predicate. *

* Does not make copies of any underlying collections. * * @param predicate a predicate; not null. * 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 ImmutableVector} */ @Override default ImmutableVector dropWhile(Fn1 predicate) { return ImmutableVectors.dropWhile(predicate, this); } /** * Maps a function over this {@code ImmutableVector}. *

* Returns a new {@link ImmutableVector} 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 ImmutableVector} 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 ImmutableVector} of the same size */ @Override default ImmutableVector fmap(Fn1 f) { return ImmutableVectors.map(f, this); } /** * Returns a {@code NonEmptyIterable} containing the inits of this {@code ImmutableVector}. *

* The first value will be this {@code ImmutableVector} and the final one will be an empty {@code Vector}, * with the intervening values the results of successive applications of {@code init}. * * @return a {@code NonEmptyIterable} over all the inits of this {@code ImmutableVector} */ @Override default ImmutableNonEmptyFiniteIterable> inits() { return ImmutableVectors.inits(this); } /** * Returns an {@code ImmutableFiniteIterable} of contiguous groups of elements in this {@code ImmutableVector} 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 ImmutableFiniteIterable>} containing the contiguous groups */ @Override default ImmutableFiniteIterable> magnetizeBy(Fn2 predicate) { return ImmutableVectors.magnetizeBy(predicate, this); } /** * Creates an {@code ImmutableVector} with this {@code ImmutableVector}'s elements in reversed order. *

* Does not make copies of any underlying collections. * * @return an {@code ImmutableVector} */ @Override default ImmutableVector reverse() { return ImmutableVectors.reverse(this); } /** * Creates a slice of this {@code ImmutableVector}. *

* Does not make copies of any underlying collections. *

* Use caution when taking a small slice of a huge {@code ImmutableVector} that you no longer need. * The smaller slice will hold onto a reference of the larger one, and will prevent it from being GC'ed. * To avoid this situation, use {@link Vector#copySliceFrom} instead. * * @param startIndex the index of the element to begin the slice. * Must be >= 0. * May exceed the size of this {@code ImmutableVector}, in which case an empty {@code ImmutableVector} will be returned. * @param endIndexExclusive the end index (exclusive) of the slice. Must be >= {@code startIndex}. * May exceed the size of this {@code ImmutableVector}, in which case the slice will * contain as many elements as available. * @return an {@code ImmutableVector} */ @Override default ImmutableVector slice(int startIndex, int endIndexExclusive) { return ImmutableVectors.slice(startIndex, endIndexExclusive, this); } /** * Splits this {@code ImmutableVector} into a prefix/suffix pair according to a predicate. *

* Does not make copies of any underlying collections. *

* Note that vector.span(p) is equivalent to, but possibly more efficient than * tuple(vector.takeWhile(p), vector.dropWhile(p)) * * @param predicate a predicate; not null. * This function should be referentially transparent and not perform side-effects. * It may be called zero or more times for each element. * @return a {@code Tuple2} contains of {@code ImmutableVector}s, one of which containing the first {@code index} elements * that satisfied the predicate, the second containing the other elements. */ @Override default Tuple2, ImmutableVector> span(Fn1 predicate) { return ImmutableVectors.span(predicate, this); } /** * Splits this {@code ImmutableVector} into two at a given position. *

* Does not make copies of any underlying collections. *

* Note that vector.splitAt(n) is equivalent to, but possibly more efficient than * tuple(vector.take(n), vector.drop(n)) * * @param index the position at which to split. * Must be >= 0; * @return a {@code Tuple2} contains of {@code ImmutableVector}s, one of which containing the first {@code index} elements, * the second containing the other elements. */ @Override default Tuple2, ImmutableVector> splitAt(int index) { return ImmutableVectors.splitAt(index, this); } /** * Returns a {@code NonEmptyIterable} containing the tails of this {@code ImmutableVector}. *

* The first value will be this {@code ImmutableVector} and the final one will be an empty {@code ImmutableVector}, * with the intervening values the results of successive applications of {@code tail}. * * @return a {@code NonEmptyIterable} over all the tails of this {@code ImmutableVector} */ @Override default ImmutableNonEmptyFiniteIterable> tails() { return ImmutableVectors.tails(this); } /** * Returns a new {@code ImmutableVector} containing at most the first {@code count} elements of this {@code ImmutableVector}. *

* Does not make copies of any underlying collections. *

* Use caution when taking a small slice of a huge {@link ImmutableVector} that you no longer need. * The smaller slice will hold onto a reference of the larger one, and will prevent it from being GC'ed. * To avoid this situation, use {@link Vector#copyFrom(int, Iterable)} instead. * * @param count the maximum number of elements to take from this {@code ImmutableVector}. * Must be >= 0. * May exceed size of this {@code ImmutableVector}. * @return an {@code ImmutableVector} */ @Override default ImmutableVector take(int count) { return ImmutableVectors.take(count, this); } /** * Returns a new {@code ImmutableVector} containing at most the last {@code count} elements of this {@code ImmutableVector}. *

* Does not make copies of any underlying collections. *

* Use caution when taking a small slice of a huge {@link ImmutableVector} that you no longer need. * The smaller slice will hold onto a reference of the larger one, and will prevent it from being GC'ed. * To avoid this situation, use {@link Vector#copyFrom(int, Iterable)} instead. * * @param count the maximum number of elements to take from this {@code ImmutableVector}. * Must be >= 0. * May exceed size of this {@code Vector}. * @return an {@code ImmutableVector} */ @Override default ImmutableVector takeRight(int count) { return ImmutableVectors.takeRight(count, this); } /** * Returns a new {@code ImmutableVector} containing the longest prefix of elements this {@code ImmutableVector} that satisfy a predicate. *

* Does not make copies of any underlying collections. * * @param predicate a predicate; not null. * 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 ImmutableVector} */ @Override default ImmutableVector takeWhile(Fn1 predicate) { return ImmutableVectors.takeWhile(predicate, this); } /** * Returns an {@code ImmutableVector} containing the same elements as this one. *

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

* If successful, returns a {@link ImmutableNonEmptyVector} containing the same elements as this one, wrapped in a {@link Maybe#just}. *

* If this {@code ImmutableVector} is empty, returns {@link Maybe#nothing}. *

* Does not make copies of any underlying collections. * * @return a {@code Maybe>} */ @Override default Maybe> toNonEmpty() { return ImmutableVectors.maybeNonEmptyConvert(this); } /** * Attempts to convert this {@code ImmutableVector} to an {@code ImmutableNonEmptyVector}. *

* If successful, returns a {@link ImmutableNonEmptyVector} containing the same elements as this one. * Use this if you are confident that this {@link ImmutableVector} is not empty. *

* If this {@code ImmutableVector} is empty, throws an {@link IllegalArgumentException}. *

* Does not make copies of any underlying collections. * * @return an {@code ImmutableNonEmptyVector} * @throws IllegalArgumentException if this {@code ImmutableVector} is empty */ @Override default ImmutableNonEmptyVector toNonEmptyOrThrow() { return ImmutableVectors.nonEmptyConvertOrThrow(this); } /** * Zips together this {@code ImmutableVector} with another {@code ImmutableVector} by applying a zipping function. *

* Applies the function to the successive elements of of each {@code ImmutableVector} 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 ImmutableVector} * @param The element type of the other {@code ImmutableVector} * @param The element type of the result * @return An {@code ImmutableVector} */ default ImmutableVector zipWith(Fn2 fn, ImmutableVector other) { return ImmutableVectors.zipWith(fn, this, other); } /** * Zips this {@code ImmutableVector} with its indices. *

* Does not make copies of any underlying collections. * * @return a new {@code ImmutableVector} containing pairs consisting of all elements of this {@code ImmutableVector} paired with their index. * Indices start at 0. */ @Override default ImmutableVector> zipWithIndex() { return ImmutableVectors.zipWithIndex(this); } /** * Creates a new {@code VectorBuilder}. * * @param the element type * @return an empty {@link VectorBuilder} */ static VectorBuilder builder() { return emptyVectorBuilder(nothing()); } /** * Creates a new {@code VectorBuilder} with an initial capacity hint. * * @param initialCapacity an initial capacity hint. * Must be >= 0. * @param the element type * @return an empty {@link VectorBuilder} */ static VectorBuilder builder(int initialCapacity) { return emptyVectorBuilder(just(initialCapacity)); } }