dev.marksman.collectionviews.NonEmptySet Maven / Gradle / Ivy
Show all versions of collection-views Show documentation
package dev.marksman.collectionviews;
import com.jnape.palatable.lambda.adt.Maybe;
import dev.marksman.enhancediterables.NonEmptyFiniteIterable;
import dev.marksman.enhancediterables.NonEmptyIterable;
import static com.jnape.palatable.lambda.adt.Maybe.just;
/**
* A {@code Set} that is guaranteed at compile-time to contain at least one element.
*
* In addition to guarantees of {@link Set}, provides the following benefits:
*
* - {@link NonEmptySet#head} method that returns an element.
* - Implements {@link NonEmptyIterable}.
*
*
* @param the element type
*/
public interface NonEmptySet extends NonEmptyFiniteIterable, Set {
/**
* Since a {@code NonEmptySet} already contains only distinct values, this method always
* returns itself.
*
* @return itself
*/
@Override
default NonEmptySet distinct() {
return this;
}
/**
* Tests whether this {@code NonEmptySet} is empty.
*
* Always returns false for {@link NonEmptySet}s.
*
* @return always false
*/
@Override
default boolean isEmpty() {
return false;
}
/**
* Converts this {@code NonEmptySet} to an {@code ImmutableNonEmptySet}.
*
* This method will make a copy of the underlying data structure if necessary to guarantee immutability.
*
* If this {@link NonEmptySet} is already an {@link ImmutableNonEmptySet}, no copies are made and this method is a no-op.
*
* @return an {@code ImmutableNonEmptySet} of the same type and containing the same elements
*/
@Override
default ImmutableNonEmptySet toImmutable() {
return ImmutableSets.ensureImmutable(this);
}
/**
* Attempts to convert this {@code Set} to a {@code NonEmptySet}.
*
* Since this will always be successful for {@link NonEmptySet}s,
* this method always returns itself wrapped in a {@link Maybe#just}.
*
* Does not make copies of any underlying data structures.
*
* @return this {@code NonEmptySet} wrapped in a {@link Maybe#just}
*/
@Override
default Maybe extends NonEmptySet> toNonEmpty() {
return just(this);
}
/**
* Attempts to convert this {@code Set} to a {@code NonEmptySet}.
*
* Since this will always be successful for {@link NonEmptySet}s,
* this method always returns itself.
*
* Does not make copies of any underlying data structures.
*
* @return this {@code NonEmptySet}
*/
@Override
default NonEmptySet toNonEmptyOrThrow() {
return this;
}
/**
* Creates a {@code ImmutableNonEmptySet} with the given elements.
*
* @param first the first element
* @param more the remaining elements
* @param the element type
* @return an {@code ImmutableNonEmptySet}
*/
@SuppressWarnings("varargs")
@SafeVarargs
static ImmutableNonEmptySet of(A first, A... more) {
return Sets.nonEmptySetOf(first, more);
}
/**
* Attempts to create a {@code NonEmptySet} that wraps a {@code java.util.Set}.
*
* Does not make any copies of the given {@link java.util.Set}.
* The created {@link NonEmptySet} will hold a reference to the given {@link java.util.Set}, but will not alter it in any way.
*
* Bearers of the {@code NonEmptySet} will be unable to gain access to the underlying {@link java.util.Set}, it is safe to share.
*
* Since no copy is made, be aware that anyone that holds a direct reference to the underlying {@code Set} can still mutate it.
* Mutating the underlying {@code Set} is not advised.
* Operations that change the size of the underlying {@code Set} will result in unpredictable behavior.
* Use {@link Vector#copyFrom} if you want to avoid this situation.
*
* @param underlying {@code java.util.Set} to wrap; not null
* @param the element type
* @return a {@code NonEmptySet} wrapped in a {@link Maybe#just} if {@code underlying} is non-empty;
* {@link Maybe#nothing} otherwise.
*/
static Maybe> maybeWrap(java.util.Set underlying) {
return Sets.maybeNonEmptyWrap(underlying);
}
/**
* Attempts to create a {@code NonEmptySet} that wraps a {@code java.util.Set}.
* If it is not possible, throws an {@link IllegalArgumentException}.
*
* Does not make any copies of the given {@link java.util.Set}.
* The created {@link NonEmptySet} will hold a reference to the given {@code java.util.Set}, but will not alter it in any way.
*
* Bearers of the created {@link NonEmptySet} will be unable to gain access to the underlying {@code Set}, it is safe to share.
*
* Since no copy is made, be aware that anyone that holds a direct reference to the underlying {@code Set} can still mutate it.
* Mutating the underlying {@code Set} is not advised.
* Operations that change the size of the underlying {@code Set} will result in unpredictable behavior.
* Use {@link NonEmptySet#copyFromOrThrow(Iterable)} if you want to avoid this situation.
*
* @param underlying {@code java.util.Set} to wrap; not null
* @param the element type
* @return a {@code NonEmptySet} if {@code underlying} is non-empty; throws an {@link IllegalArgumentException} otherwise
*/
static NonEmptySet wrapOrThrow(java.util.Set underlying) {
return Sets.nonEmptyWrapOrThrow(underlying);
}
/**
* Attempts to create an {@code ImmutableNonEmptySet} that is copied from any {@code Iterable}.
*
* The entire {@link Iterable} will be eagerly iterated.
* Be careful not to pass in an infinite {@code Iterable} or this method will not terminate.
*
* If necessary to guarantee immutability, this method will make a copy of the data provided.
* If {@code source} already is an {@link ImmutableNonEmptySet}, it will be returned directly.
*
* @param source an {@code Iterable} that may be iterated eagerly in its entirety; not null
* @param the element type
* @return an {@code ImmutableNonEmptySet} wrapped in a {@link Maybe#just} if {@code source} is non-empty;
* {@link Maybe#nothing} otherwise.
*/
static Maybe> maybeCopyFrom(Iterable source) {
return ImmutableSets.maybeNonEmptyCopyFrom(source);
}
/**
* Attempts to create an {@code ImmutableNonEmptySet} that is copied from an array.
*
* @param source the array to copy from.
* Not null.
* This method will not alter or hold on to a reference of this array.
* @param the element type
* @return an {@code ImmutableNonEmptySet} wrapped in a {@link Maybe#just} if {@code source} is non-empty;
* {@link Maybe#nothing} otherwise.
*/
static Maybe> maybeCopyFrom(A[] source) {
return ImmutableSets.maybeNonEmptyCopyFrom(source);
}
/**
* Attempts to create an {@code ImmutableNonEmptySet} that is copied from any {@link Iterable}, but consuming a maximum number of elements.
*
* The {@link Iterable} will be eagerly iterated, but only up to a maximum of {@code maxCount} elements.
* If {@code maxCount} elements are not available, then the all of the elements available will be returned.
*
* This method will make a copy of the data provided, unless {@code source} is
* an {@link ImmutableNonEmptySet} and its size is equal to {@code maxCount},
* in which case it will be returned directly.
*
* @param maxCount the maximum number of elements to consume from the source. Must be >= 0.
* If 0, this method will always return {@link Maybe#nothing}.
* @param source an {@code Iterable} that will be iterated eagerly for up to {@code maxCount} elements.
* Not null.
* It is safe for {@code source} to be infinite.
* @param the element type
* @return an {@code ImmutableNonEmptySet} wrapped in a {@link Maybe#just} if {@code source} is non-empty;
* {@link Maybe#nothing} otherwise.
*/
static Maybe> maybeCopyFrom(int maxCount, Iterable source) {
return ImmutableSets.maybeNonEmptyCopyFrom(maxCount, source);
}
/**
* Attempts to create an {@code ImmutableNonEmptySet} that is copied from an array, but with a maximum number of elements.
*
* @param maxCount the maximum number of elements to copy from the array.
* Must be >= 0.
* If 0, this method will always return {@link Maybe#nothing}.
* @param source the array to copy from.
* Not null.
* This method will not alter or hold on to a reference of this array.
* @param the element type
* @return an {@code ImmutableNonEmptySet} wrapped in a {@link Maybe#just} if {@code source} is non-empty;
* {@link Maybe#nothing} otherwise.
*/
static Maybe> maybeCopyFrom(int maxCount, A[] source) {
return ImmutableSets.maybeNonEmptyCopyFrom(maxCount, source);
}
/**
* Attempts to create an {@code ImmutableNonEmptySet} from any {@code Iterable}.
* If the {@link Iterable} is empty, throws an {@link IllegalArgumentException}.
*
* The entire {@link Iterable} will be eagerly iterated.
* Be careful not to pass in an infinite {@code Iterable} or this method will not terminate.
*
* If necessary to guarantee immutability, this method will make a copy of the data provided.
* If {@code source} already is an {@link ImmutableNonEmptySet}, it will be returned directly.
*
* @param source an {@code Iterable} that will be iterated eagerly in its entirety; not null
* @param the element type
* @return an {@code ImmutableNonEmptySet}
*/
static ImmutableNonEmptySet copyFromOrThrow(Iterable source) {
return ImmutableSets.nonEmptyCopyFromOrThrow(source);
}
/**
* Attempts to create an {@code ImmutableNonEmptySet} that is copied from an array.
* If the array is empty, throws an {@link IllegalArgumentException}.
*
* @param source the array to copy from.
* Not null.
* This method will not alter or hold on to a reference of this array.
* @param the element type
* @return an {@code ImmutableNonEmptySet}
*/
static ImmutableNonEmptySet copyFromOrThrow(A[] source) {
return ImmutableSets.nonEmptyCopyFromOrThrow(source);
}
/**
* Attempts to create an {@code ImmutableNonEmptySet} from any {@code Iterable}, but consuming a maximum number of elements.
* If the {@link Iterable} is empty, throws an {@link IllegalArgumentException}.
*
* The {@code Iterable} will be eagerly iterated, but only up to a maximum of {@code maxCount} elements.
* If {@code maxCount} elements are not available, then the all of the elements available will be returned.
*
* This method will make a copy of the data provided, unless {@code source} is
* an {@link ImmutableNonEmptySet} and its size is equal to {@code maxCount},
* in which case it will be returned directly.
*
*
* @param maxCount the maximum number of elements to consume from the source.
* Must be >= 1.
* @param source an {@code Iterable} that will be iterated eagerly for up to {@code maxCount} elements.
* Not null.
* It is safe for {@code source} to be infinite.
* @param the element type
* @return an {@code ImmutableNonEmptySet}
*/
static ImmutableNonEmptySet copyFromOrThrow(int maxCount, Iterable source) {
return ImmutableSets.nonEmptyCopyFromOrThrow(maxCount, source);
}
/**
* Attempts to create an {@code ImmutableNonEmptySet} that is copied from an array, but with a maximum number of elements.
* If the array is empty, throws an {@link IllegalArgumentException}.
*
* @param maxCount the maximum number of elements to copy from the array.
* Must be >= 1.
* @param source the array to copy from.
* Not null.
* This method will not alter or hold on to a reference of this array.
* @param the element type
* @return an {@code ImmutableNonEmptySet}
*/
static ImmutableNonEmptySet copyFromOrThrow(int maxCount, A[] source) {
return ImmutableSets.nonEmptyCopyFromOrThrow(maxCount, source);
}
}