Class NonEmptyList<T>

java.lang.Object
dmx.fun.NonEmptyList<T>
Type Parameters:
T - the type of elements in this list
All Implemented Interfaces:
Iterable<T>, Collection<T>, SequencedCollection<T>

@NullMarked public final class NonEmptyList<T> extends Object implements SequencedCollection<T>
An immutable, non-empty list: a list guaranteed at construction time to contain at least one element.

This type makes the non-emptiness constraint part of the static type system. APIs that require at least one item can declare NonEmptyList<T> instead of List<T> and eliminate runtime emptiness checks entirely.

NonEmptyList<T> pairs naturally with Validated's error accumulation, which always produces at least one error when invalid.

This class is @NullMarked: all elements and parameters are non-null by default.

The rationale for introducing dedicated non-empty collection types instead of using standard JDK types with runtime checks is documented in ADR-018 — NonEmptyList<T>, NonEmptySet<T>, NonEmptyMap<K,V> as structural guarantee types.

  • Method Details

    • of

      public static <T> NonEmptyList<T> of(T head, List<? extends T> tail)
      Creates a NonEmptyList with the given head and tail.
      Type Parameters:
      T - the element type
      Parameters:
      head - the first (mandatory) element; must not be null
      tail - the remaining elements; must not be null; elements must not be null
      Returns:
      a new NonEmptyList
      Throws:
      NullPointerException - if head, tail, or any tail element is null
    • singleton

      public static <T> NonEmptyList<T> singleton(T head)
      Creates a NonEmptyList containing exactly one element.
      Type Parameters:
      T - the element type
      Parameters:
      head - the sole element; must not be null
      Returns:
      a singleton NonEmptyList
      Throws:
      NullPointerException - if head is null
    • fromList

      public static <T> Option<NonEmptyList<T>> fromList(List<? extends T> list)
      Attempts to construct a NonEmptyList from a plain List.
      Type Parameters:
      T - the element type
      Parameters:
      list - the source list; must not be null; elements must not be null
      Returns:
      Option.some(Object) wrapping the NonEmptyList if the list is non-empty, or Option.none() if the list is empty
      Throws:
      NullPointerException - if list or any element is null
    • fromOptional

      public static <T> Option<NonEmptyList<T>> fromOptional(Optional<? extends T> optional)
      Attempts to construct a singleton NonEmptyList from a JDK Optional.
      Type Parameters:
      T - the element type
      Parameters:
      optional - the source optional; must not be null
      Returns:
      Option.some(Object) wrapping a singleton NonEmptyList if the optional is present, or Option.none() if the optional is empty
      Throws:
      NullPointerException - if optional is null
    • head

      public T head()
      Returns the first element of this list.
      Returns:
      the head element (never null)
    • getFirst

      public T getFirst()
      Returns the first element of this list. Alias for head().

      Implements SequencedCollection.getFirst().

      Specified by:
      getFirst in interface SequencedCollection<T>
      Returns:
      the first element (never null)
    • getLast

      public T getLast()
      Returns the last element of this list.

      Implements SequencedCollection.getLast().

      Specified by:
      getLast in interface SequencedCollection<T>
      Returns:
      the last element (never null)
    • reversed

      public NonEmptyList<T> reversed()
      Returns a new NonEmptyList with all elements in reverse order.

      Implements SequencedCollection.reversed().

      Specified by:
      reversed in interface SequencedCollection<T>
      Returns:
      a reversed copy of this list
    • addFirst

      public void addFirst(T t)
      Unsupported — NonEmptyList is immutable.
      Specified by:
      addFirst in interface SequencedCollection<T>
      Throws:
      UnsupportedOperationException - always
    • addLast

      public void addLast(T t)
      Unsupported — NonEmptyList is immutable.
      Specified by:
      addLast in interface SequencedCollection<T>
      Throws:
      UnsupportedOperationException - always
    • removeFirst

      public T removeFirst()
      Unsupported — NonEmptyList is immutable.
      Specified by:
      removeFirst in interface SequencedCollection<T>
      Throws:
      UnsupportedOperationException - always
    • removeLast

      public T removeLast()
      Unsupported — NonEmptyList is immutable.
      Specified by:
      removeLast in interface SequencedCollection<T>
      Throws:
      UnsupportedOperationException - always
    • tail

      public List<T> tail()
      Returns an unmodifiable view of all elements after the head. May be empty if this is a singleton list.
      Returns:
      the tail (never null, may be empty)
    • toList

      public List<T> toList()
      Returns an unmodifiable List containing all elements (head followed by tail).
      Returns:
      a new unmodifiable list with all elements
    • size

      public int size()
      Returns the number of elements in this list. Always ≥ 1.
      Specified by:
      size in interface Collection<T>
      Returns:
      the size
    • map

      public <R> NonEmptyList<R> map(Function<? super T, ? extends R> mapper)
      Applies mapper to every element and returns a new NonEmptyList of the results. The structure (head/tail split) is preserved.
      Type Parameters:
      R - the result element type
      Parameters:
      mapper - a non-null function to apply to each element; must not return null
      Returns:
      a new NonEmptyList of mapped values
      Throws:
      NullPointerException - if mapper is null or returns null
    • append

      public NonEmptyList<T> append(T element)
      Returns a new NonEmptyList with element appended at the end.
      Parameters:
      element - the element to append; must not be null
      Returns:
      a new NonEmptyList with the element appended
      Throws:
      NullPointerException - if element is null
    • prepend

      public NonEmptyList<T> prepend(T element)
      Returns a new NonEmptyList with element prepended at the front.
      Parameters:
      element - the element to prepend; must not be null
      Returns:
      a new NonEmptyList with the element prepended
      Throws:
      NullPointerException - if element is null
    • concat

      public NonEmptyList<T> concat(NonEmptyList<T> other)
      Returns a new NonEmptyList that is the concatenation of this list and other.
      Parameters:
      other - the list to append; must not be null
      Returns:
      a new NonEmptyList containing all elements of both lists
      Throws:
      NullPointerException - if other is null
    • toNonEmptySet

      public NonEmptySet<T> toNonEmptySet()
      Converts this list to a NonEmptySet, preserving the head element and deduplicating the tail in insertion order. Duplicate elements are silently dropped; the head is always retained.
      Returns:
      a NonEmptySet<T> with the same distinct elements
    • toStream

      public Stream<T> toStream()
      Returns a sequential Stream of all elements (head first, then tail). Does not materialize an intermediate list.
      Returns:
      a Stream<T> over all elements
    • collector

      public static <T> Collector<T, ?, Option<NonEmptyList<T>>> collector()
      Returns a Collector that accumulates a Stream<T> into an Option<NonEmptyList<T>>.

      Produces Option.some(Object) if the stream has at least one element, or Option.none() if the stream is empty.

      Type Parameters:
      T - the element type
      Returns:
      a Collector producing Option<NonEmptyList<T>>
    • toNonEmptyList

      public static <T> Collector<T, ?, Option<NonEmptyList<T>>> toNonEmptyList()
      Alias for collector().

      Returns a Collector that accumulates a Stream<T> into an Option<NonEmptyList<T>>. Produces Option.some(Object) if the stream has at least one element, or Option.none() if the stream is empty.

      Option<NonEmptyList<String>> tags =
          Stream.of("java", "fp", "dmx-fun")
                .collect(NonEmptyList.toNonEmptyList());
      // Some(["java", "fp", "dmx-fun"])
      
      Option<NonEmptyList<String>> empty =
          Stream.<String>empty()
                .collect(NonEmptyList.toNonEmptyList());
      // None
      
      Type Parameters:
      T - the element type
      Returns:
      a Collector producing Option<NonEmptyList<T>>
    • sequence

      public static <T> Option<NonEmptyList<T>> sequence(NonEmptyList<Option<T>> nel)
      Sequences a NonEmptyList of Options into an Option of a NonEmptyList.

      Returns Option.some(Object) containing all unwrapped values if every element is Option.some(Object); returns Option.none() as soon as any element is Option.none().

      Type Parameters:
      T - the element type
      Parameters:
      nel - a NonEmptyList<Option<T>>; must not be null
      Returns:
      Some(NonEmptyList<T>) if all options are present, None otherwise
      Throws:
      NullPointerException - if nel is null
    • sequenceTry

      public static <T> Try<NonEmptyList<T>> sequenceTry(NonEmptyList<Try<T>> nel)
      Sequences a NonEmptyList of Trys into a Try of a NonEmptyList.

      Returns Try.success(Object) containing all unwrapped values if every element is a success; returns Try.failure(Throwable) from the first failing element (fail-fast in inspection — the method stops iterating after the first failure; elements are already materialized in the list before sequencing, so later elements are not inspected but were already evaluated).

      Type Parameters:
      T - the success value type
      Parameters:
      nel - a NonEmptyList<Try<T>>; must not be null
      Returns:
      Success(NonEmptyList<T>) if all succeed, Failure from the first failing element otherwise
      Throws:
      NullPointerException - if nel is null
    • sequenceEither

      public static <E,T> Either<E, NonEmptyList<T>> sequenceEither(NonEmptyList<Either<E,T>> nel)
      Sequences a NonEmptyList of Eithers into an Either of a NonEmptyList.

      Returns Either.right(Object) containing all unwrapped values if every element is right; returns Either.left(Object) from the first left element (fail-fast in inspection — the method stops iterating after the first left; elements are already materialized in the list before sequencing, so later elements are not inspected but were already evaluated).

      Type Parameters:
      E - the left (error) type
      T - the right (success) type
      Parameters:
      nel - a NonEmptyList<Either<E, T>>; must not be null
      Returns:
      right(NonEmptyList<T>) if all are right, left(E) from the first left element otherwise
      Throws:
      NullPointerException - if nel is null
    • sequenceResult

      public static <T,E> Result<NonEmptyList<T>, E> sequenceResult(NonEmptyList<Result<T,E>> nel)
      Sequences a NonEmptyList of Results into a Result of a NonEmptyList.

      Returns Result.ok(Object) containing all unwrapped values if every element is ok; returns Result.err(Object) from the first error element (fail-fast in inspection — the method stops iterating after the first err; elements are already materialized in the list before sequencing, so later elements are not inspected but were already evaluated).

      Type Parameters:
      T - the ok value type
      E - the error type
      Parameters:
      nel - a NonEmptyList<Result<T, E>>; must not be null
      Returns:
      ok(NonEmptyList<T>) if all succeed, err(E) from the first error element otherwise
      Throws:
      NullPointerException - if nel is null
    • isEmpty

      public boolean isEmpty()
      Always false — a NonEmptyList always has at least one element.
      Specified by:
      isEmpty in interface Collection<T>
    • contains

      public boolean contains(Object o)
      Specified by:
      contains in interface Collection<T>
    • containsAll

      public boolean containsAll(Collection<?> c)
      Specified by:
      containsAll in interface Collection<T>
    • toArray

      public Object[] toArray()
      Specified by:
      toArray in interface Collection<T>
    • toArray

      public <E> E[] toArray(E[] a)
      Specified by:
      toArray in interface Collection<T>
    • add

      public boolean add(T t)
      Specified by:
      add in interface Collection<T>
      Throws:
      UnsupportedOperationException - always — NonEmptyList is immutable
    • remove

      public boolean remove(Object o)
      Specified by:
      remove in interface Collection<T>
      Throws:
      UnsupportedOperationException - always — NonEmptyList is immutable
    • addAll

      public boolean addAll(Collection<? extends T> c)
      Specified by:
      addAll in interface Collection<T>
      Throws:
      UnsupportedOperationException - always — NonEmptyList is immutable
    • removeAll

      public boolean removeAll(Collection<?> c)
      Specified by:
      removeAll in interface Collection<T>
      Throws:
      UnsupportedOperationException - always — NonEmptyList is immutable
    • retainAll

      public boolean retainAll(Collection<?> c)
      Specified by:
      retainAll in interface Collection<T>
      Throws:
      UnsupportedOperationException - always — NonEmptyList is immutable
    • removeIf

      public boolean removeIf(Predicate<? super T> filter)
      Specified by:
      removeIf in interface Collection<T>
      Throws:
      UnsupportedOperationException - always — NonEmptyList is immutable
    • clear

      public void clear()
      Specified by:
      clear in interface Collection<T>
      Throws:
      UnsupportedOperationException - always — NonEmptyList is immutable
    • iterator

      public Iterator<T> iterator()
      Returns an iterator over all elements (head first, then tail). Does not materialize an intermediate list.
      Specified by:
      iterator in interface Collection<T>
      Specified by:
      iterator in interface Iterable<T>
      Returns:
      an iterator
    • equals

      public boolean equals(Object obj)
      Specified by:
      equals in interface Collection<T>
      Overrides:
      equals in class Object
    • hashCode

      public int hashCode()
      Specified by:
      hashCode in interface Collection<T>
      Overrides:
      hashCode in class Object
    • toString

      public String toString()
      Overrides:
      toString in class Object