de.caff.generics

## Interface IntCountable

- All Superinterfaces:
    java.lang.Iterable<java.lang.Integer>, PrimitiveIntIterable, Sizeable
  All Known Subinterfaces:
    ExpandableIntIndexable, IntIndexable, MutableIntIndexable
  All Known Implementing Classes:
    IntCountable.Base, IntIndexable.Base, IntPair, MutableIntIndexable.Base

      public interface IntCountable
      extends PrimitiveIntIterable, Sizeable

  Something containing a defined number of int values which can be iterated over.

  Having a known size usually helps in optimization, e.g. when copying.

  This is meant to be used as a read-only interface, although `Iterable` basically exports mutability via `Iterator.remove()`. This interface extends `Iterable` nevertheless so implementations can be used in enhanced `for` loops. In an ideal world Java collections should implement this interface to provide a better compile-time read-only access compared to the `Collections#unmodifiableCollection()` which will result in runtime errors when mutating.

  To allow living in a standard Java environment this interface provides methods `asCollection()` to view it as an unmodifiable collection and `viewCollection(Collection)` allowing to view a collection as `IntCountable`.

  A countable can also view an array or part of it (`IntIndexable.viewArray(int[])` and `IntIndexable.viewArray(int[], int, int)`), and can be converted to an array.

  Last not least an `empty countable` is useful sometimes.

  Since:
    December 24, 2020
  Author:
    Rammi

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Interface and Description
    --- | ---
    `static class` | `IntCountable.Base` Abstract base class which provides useful implementations for `Object.equals(Object)`, `Object.hashCode()`, `Object.toString()`.

  - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `static IntCountable` | `EMPTY` Basic implementation of an empty countable Don't use this, use `empty()`.

    - ### Fields inherited from interface de.caff.generics.PrimitiveIntIterable

      `EMPTY_INT_ITERATOR`

    - ### Fields inherited from interface de.caff.generics.Sizeable

      `NULL`

  - ### Method Summary

    All Methods Static Methods Instance Methods Default Methods
    Modifier and Type | Method and Description
    --- | ---
    `default void` | `addAllTo(java.util.Collection<? super java.lang.Integer> collection)` Add all entries of this countable to the given collection.
    `default int` | `addToArray(int[] array, int arrayPos)` Add the complete content of this countable to the given array.
    `default IntCountable.Base` | `asBase()` Convert this into a base countable.
    `default java.util.Collection<java.lang.Integer>` | `asCollection()` View this countable as an unmodifiable standard Java collection.
    `static IntCountable` | `empty()` Get an empty countable.
    `default PrimitiveIntIterable` | `filtered(java.util.function.IntPredicate filter)` Get a filtered view of this countable.
    `default int` | `first()` Get the first value.
    `default IntIndexable` | `frozen()` Get a frozen version of this countable.
    `default boolean` | `isEmpty()` Is this countable empty?
    `default <E> boolean` | `isEqual(IntCountable other)` Does this countable equal another one?
    `default boolean` | `isSorted(IntOrdering order)` Is this countable ordered according to the given sort order?
    `default boolean` | `isStrictlySorted(IntOrdering order)` Is this countable strictly ordered according to the given sort order?
    `default int` | `last()` Get the last value.
    `static IntCountable` | `singleton(int singleValue)` Get an int countable with a single value.
    `default IntIndexable` | `sorted(IntOrdering order)` Get a sorted frozen version of this countable.
    `default int[]` | `toArray()` Copy the content of this countable to an array.
    `default java.util.ArrayList<java.lang.Integer>` | `toList()` Get a list which is the copy of this countable.
    `static java.lang.String` | `toString(IntCountable countable)` Create a string representation of the given countable.
    `static IntCountable` | `uniform(int value, int count)` Get a countable which is returning the same value multiple times.
    `default <R> Countable<R>` | `view(java.util.function.IntFunction<? extends R> mapper)` View this int countable as if it has another type.
    `static IntCountable` | `viewCollection(java.util.Collection<? extends java.lang.Number> collection)` View a collection as if it were a countable.
    `static <E> IntCountable` | `viewCollection(java.util.Collection<E> collection, java.util.function.ToIntFunction<? super E> intMapper)` View a collection as if it were a countable.
    `static IntCountable` | `viewCollectionN(java.util.Collection<? extends java.lang.Number> collection)` View a collection which is potentially `null` as if it were a countable.
    `static <E> IntCountable` | `viewCollectionN(java.util.Collection<E> collection, java.util.function.ToIntFunction<? super E> intMapper)` View a collection which is potentially {qcode null}as if it were a countable.

    - ### Methods inherited from interface de.caff.generics.PrimitiveIntIterable

      `average, containsInt, forEachInt, forEachIntFragile, intIterator, iterator, longSum, longSumX, spliterator, stream, sum, sumX`

    - ### Methods inherited from interface java.lang.Iterable

      `forEach`

    - ### Methods inherited from interface de.caff.generics.Sizeable

      `size`

- - ### Field Detail

    - #### EMPTY

          static final IntCountable EMPTY

      Basic implementation of an empty countable Don't use this, use `empty()`.

  - ### Method Detail

    - #### isEmpty

          default boolean isEmpty()

      Is this countable empty? An empty countable does not contain any elements which means that `Sizeable.size()` will return `0`.

      This default implementation just checks for `Sizeable.size()` returning `0`

      Returns:
        `true` if this countable is empty, `false` otherwise. Because calculating the size might be expensive sometimes in these cases implementations should override this method if possible.

    - #### asCollection

          @NotNull
          default java.util.Collection<java.lang.Integer> asCollection()

      View this countable as an unmodifiable standard Java collection.
      Returns:
        standard Java `Collection` view of this countable

    - #### toList

          @NotNull
          default java.util.ArrayList<java.lang.Integer> toList()

      Get a list which is the copy of this countable.
      Returns:
        array list with the elements of this countable

    - #### addAllTo

          default void addAllTo(@NotNull
                                java.util.Collection<? super java.lang.Integer> collection)

      Add all entries of this countable to the given collection.
      Parameters:
        `collection` - collection where all entries are added

    - #### toArray

          @NotNull
          default int[] toArray()

      Copy the content of this countable to an array.
      Returns:
        array with the copied content of this countabel

    - #### addToArray

          default int addToArray(@NotNull
                                 int[] array,
                                 int arrayPos)

      Add the complete content of this countable to the given array.
      Parameters:
        `array` - array where the content is added
        `arrayPos` - start position in hte array where the content is added
      Returns:
        array position after the added content

    - #### view

          @NotNull
          default <R> Countable<R> view(@NotNull
                                                 java.util.function.IntFunction<? extends R> mapper)

      View this int countable as if it has another type. This is a view which just converts each element when accessed.
      Type Parameters:
        `R` - resulting element type
      Parameters:
        `mapper` - converter from elements of this countable to elements of the returned countable
      Returns:
        countable view of this countable with mapped elements

    - #### filtered

          @NotNull
          default PrimitiveIntIterable filtered(@NotNull
                                                         java.util.function.IntPredicate filter)

      Get a filtered view of this countable.
      Parameters:
        `filter` - check which defines the elements which are included in the returned `Iterable`.
      Returns:
        iterable only providing the elements which `filter` accepts

    - #### sorted

          @NotNull
          default IntIndexable sorted(@NotNull
                                               IntOrdering order)

      Get a sorted frozen version of this countable.

      Often Indexables are used as a view to underlying collections. Although this interface is immutable, the underlying collection might nevertheless change. This method copies the current state of this countable into an unmodifiable state, and returns an Indexable which is sorted, stable in size and will always return the same elements in the given order.

      Parameters:
        `order` - ordering condition for the returned indexable
      Returns:
        sorted frozen indexable version of this Countable

    - #### isSorted

          default boolean isSorted(@NotNull
                                   IntOrdering order)

      Is this countable ordered according to the given sort order? This method accepts equal elements and assumes them ordered. See `isStrictlySorted(IntOrdering)` for a check which does not accept that. Empty or 1-element countables will always return `true`.
      Parameters:
        `order` - order which is checked
      Returns:
        `true` if the elements in this countable are ordered considering the given `order`
        `false` if not

    - #### isStrictlySorted

          default boolean isStrictlySorted(@NotNull
                                           IntOrdering order)

      Is this countable strictly ordered according to the given sort order? This method does consider equal elements unordered. See `isSorted(IntOrdering)` for a check which is more relaxed. Empty or 1-element countables will always return `true`.
      Parameters:
        `order` - order which is checked
      Returns:
        `true` if the elements in this countable are ordered considering the given `order`
        `false` if not

    - #### frozen

          @NotNull
          default IntIndexable frozen()

      Get a frozen version of this countable.

      Often Countables are used as a view to underlying collections. Although this interface is immutable, the underlying collection might nevertheless change. This copies the current state of this countable into an unmodifiable state, and returns a Countable which is stable in size and will returns always the same elements. This method also takes care of possibly mutable elements, which are copied when freezing and possibly also on getting.

      Calling `frozen()` again on the returned object will just return the object itself, but calling this method again will always create a new object.

      Returns:
        frozen indexable version of this Countable

    - #### first

          default int first()

      Get the first value.
      Returns:
        first value in this countable
      Throws:
        `java.util.NoSuchElementException` - if this countable is empty

    - #### last

          default int last()

      Get the last value. In the base implementation iterates over all elements in this countable to reach the last element.
      Returns:
        last element in this countable

    - #### asBase

          @NotNull
          default IntCountable.Base asBase()

      Convert this into a base countable. Base countables have useful default implementation for `Object.equals(Object)`, `Object.hashCode()`, and `Object.toString()`.
      Returns:
        base indexable

    - #### isEqual

          default <E> boolean isEqual(@NotNull
                                      IntCountable other)

      Does this countable equal another one?

      This method is more flexible than standard `Object.equals(Object)` because it allows to define the check for element equality.

      Type Parameters:
        `E` - element type of other countable
      Parameters:
        `other` - other countable
      Returns:
        `true` if this and the other countable are considered equal regarding the given element check
        `false` if not

    - #### viewCollection

          @NotNull
          static IntCountable viewCollection(@NotNull
                                                      java.util.Collection<? extends java.lang.Number> collection)

      View a collection as if it were a countable. This creates read-only access to the underlying collection.

      As this is a view any changes in the underlying collection will be reflected from the returned `Countable`. If this may pose a problem copy the collection first:

      >      Countable.viewCollection(new ArrayList<>(collection));

      Parameters:
        `collection` - collection to view
      Returns:
        countable view of the given `collection`

    - #### viewCollectionN

          @NotNull
          static IntCountable viewCollectionN(@Nullable
                                                       java.util.Collection<? extends java.lang.Number> collection)

      View a collection which is potentially `null` as if it were a countable. This creates read-only access to the underlying collection.

      As this is a view any changes in the underlying collection will be reflected from the returned `Countable`. If this may pose a problem copy the collection first:

      >      Countable.viewCollection(new ArrayList<>(collection));

      or call frozen() on the returned countable
      Parameters:
        `collection` - collection to view
      Returns:
        countable view of the given `collection`, `empty` if `collection` is `null`

    - #### viewCollection

          @NotNull
          static <E> IntCountable viewCollection(@NotNull
                                                          java.util.Collection<E> collection,
                                                          @NotNull
                                                          java.util.function.ToIntFunction<? super E> intMapper)

      View a collection as if it were a countable. This creates read-only access to the underlying collection.

      As this is a view any changes in the underlying collection will be reflected from the returned `Countable`. If this may pose a problem copy the collection first:

      >      Countable.viewCollection(new ArrayList<>(collection));

      Type Parameters:
        `E` - valeu type of the collection
      Parameters:
        `collection` - collection to view
        `intMapper` - mapper from the collection's value type to `int`
      Returns:
        countable view of the given `collection`

    - #### viewCollectionN

          @NotNull
          static <E> IntCountable viewCollectionN(@Nullable
                                                           java.util.Collection<E> collection,
                                                           @NotNull
                                                           java.util.function.ToIntFunction<? super E> intMapper)

      View a collection which is potentially {qcode null}as if it were a countable. This creates read-only access to the underlying collection.

      As this is a view any changes in the underlying collection will be reflected from the returned `Countable`. If this may pose a problem copy the collection first:

      >      Countable.viewCollection(new ArrayList<>(collection));

      Type Parameters:
        `E` - valeu type of the collection
      Parameters:
        `collection` - collection to view
        `intMapper` - mapper from the collection's value type to `int`
      Returns:
        countable view of the given `collection`

    - #### empty

          @NotNull
          static IntCountable empty()

      Get an empty countable. This is often preferable as a return result to indicate nothing instead of returning `null`.
      Returns:
        empty countable

    - #### singleton

          @NotNull
          static IntCountable singleton(int singleValue)

      Get an int countable with a single value.
      Parameters:
        `singleValue` - single value of this countable
      Returns:
        countable of size 1 with the given element

    - #### uniform

          @NotNull
          static IntCountable uniform(int value,
                                               int count)

      Get a countable which is returning the same value multiple times. This can be useful under special circumstances.
      Parameters:
        `value` - value returned from this countable on each `next()` call of its iterator
        `count` - number of times the same value is returned from the iterator, must not be negative
      Returns:
        countable which returns `value` `count` times during iteration

    - #### toString

          @NotNull
          static java.lang.String toString(@NotNull
                                                    IntCountable countable)

      Create a string representation of the given countable.
      Parameters:
        `countable` - countable
      Returns:
        string representation