de.caff.generics

## Interface Countable<T>

- Type Parameters:
    `T` - object type of this countable
  All Superinterfaces:
    java.lang.Iterable<T>, Sizeable
  All Known Subinterfaces:
    ExpandableIndexable<T>, Indexable<T>, MultiIndexLinearizer.Sequencer, MutableIndexable<T>, OneDimensionalAccess<T>, OneDimensionalBooleanAccess, OneDimensionalBooleanReadAccess, OneDimensionalByteAccess, OneDimensionalByteReadAccess, OneDimensionalCharAccess, OneDimensionalCharReadAccess, OneDimensionalDoubleAccess, OneDimensionalDoubleReadAccess, OneDimensionalFloatAccess, OneDimensionalFloatReadAccess, OneDimensionalIntAccess, OneDimensionalIntReadAccess, OneDimensionalLongAccess, OneDimensionalLongReadAccess, OneDimensionalReadAccess<T>, OneDimensionalShortAccess, OneDimensionalShortReadAccess
  All Known Implementing Classes:
    BasicLoop, Countable.Base, Indexable.Base, IntPartitions.Partition, Loop, MultiIndexLinearizer.BasicSequencer, MutableIndexable.Base, OneDimensionalArray, OneDimensionalBooleanArray, OneDimensionalBooleanReadAccess.Base, OneDimensionalByteArray, OneDimensionalByteReadAccess.Base, OneDimensionalCharArray, OneDimensionalCharReadAccess.Base, OneDimensionalDoubleArray, OneDimensionalDoubleReadAccess.Base, OneDimensionalFloatArray, OneDimensionalFloatReadAccess.Base, OneDimensionalIntArray, OneDimensionalIntReadAccess.Base, OneDimensionalLongArray, OneDimensionalLongReadAccess.Base, OneDimensionalReadAccess.Base, OneDimensionalShortArray, OneDimensionalShortReadAccess.Base, SemVer.Prerelease

      public interface Countable<T>
      extends java.lang.Iterable<T>, Sizeable

  Something containing a defined number of arbitrary elements 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 `Countable`.

  A countable can also view an array or part of it (`viewArray(Object[])` and `viewArray(Object[], 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` | `Countable.Base<TT>` 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 Countable<java.lang.Object>` | `EMPTY` A basic implementation of an empty countable.

    - ### 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 T> collection)` Add all entries of this countable to the given collection.
    `default int` | `addToArray(T[] array, int arrayPos)` Add the complete content of this countable to the given array.
    `default Countable.Base<T>` | `asBase()` Convert this into a base countable.
    `default java.util.Collection<T>` | `asCollection()` View this countable as an unmodifiable standard Java collection.
    `static <E> Countable<E>` | `combined(Countable<? extends Countable<? extends E>> parts)` Combine several countables into one.
    `static <E> Countable<E>` | `combined(Countable<? extends E>... parts)` Combine several countables into one.
    `default boolean` | `containsEq(T elem)` Is the given element contained?
    `default boolean` | `containsRef(T elem)` Is the given element contained?
    `static <E> Countable<E>` | `downCast(Countable<? extends E> countable)` Downcast a countable of a given type so that it appears at a countable of a super type.
    `static <E> Countable<E>` | `empty()` Get an empty countable.
    `static <E1,E2> boolean` | `equal(Countable<E1> countable1, Countable<E2> countable2, java.util.function.BiPredicate<? super E1,? super E2> equalityChecker)` Are two countables equal?
    `default <E> boolean` | `equals(Countable<E> other, java.util.function.BiPredicate<? super T,? super E> elementEquals)` Does this countable equal another one?
    `default java.lang.Iterable<T>` | `filtered(java.util.function.Predicate<? super T> filter)` Get a filtered view of this countable.
    `default Indexable<T>` | `filteredToIndexable(java.util.function.Predicate<? super T> filter)` Get an indexable which contains elements from this countable which fulfill a given filter.
    `default Countable<T>` | `filterToCountable(java.util.function.Predicate<? super T> filter)` Get a countable which contains elements from this countable which fulfill a given filter condition.
    `default T` | `first()` Get the first element.
    `default T` | `firstOrNull()` Get the first element, or `null` if this countable is empty.
    `default <V> V` | `foldLeft(V initialValue, java.util.function.BiFunction<? super V,? super T,? extends V> folder)` Calculate a value from this countable by reapplying a 2-argument function for each element, with the result of the latest application and the current element.
    `default <E extends java.lang.Exception> void` | `forEachFragile(FragileProcedure1<E,? super T> consumer)` Apply a fragile consumer to each element of this countable.
    `static <TT> Indexable<TT>` | `freeze(Countable<? extends TT> countable)` Freeze a countable to an indexable.
    `static <E> Countable<E>` | `fromOptional(java.util.Optional<E> optional)` Convert a standard Optional to a Countable with either one or no element.
    `default Indexable<T>` | `frozen()` Get a frozen version of this countable.
    `default Indexable<T>` | `frozen(java.util.function.Function<? super T,? extends T> elementCloner, boolean cloneOnGet)` Get a frozen version of this countable.
    `default T` | `getAny(java.util.function.Predicate<? super T> check)` Get the first element which fulfills the predicate.
    `default <K> Dict<K,Indexable<T>>` | `groupingBy(java.util.function.Function<? super T,? extends K> keyExtractor)` Create a mapping of a key extracted from each element to groups of elements which belongs to this key.
    `default <K,V> Dict<K,Indexable<V>>` | `groupingBy(java.util.function.Function<? super T,? extends K> keyExtractor, java.util.function.Function<? super T,? extends V> valueMapper)` Create a mapping of a key extracted from each element to groups of elements which belongs to this key.
    `default boolean` | `hasAll(java.util.function.Predicate<? super T> check)` Check if all elements fulfill a given predicate.
    `default boolean` | `hasAny(java.util.function.Predicate<? super T> check)` Check if any element fulfills a given predicate.
    `default boolean` | `isEmpty()` Is this countable empty?
    `default boolean` | `isSorted(java.util.Comparator<? super T> order)` Is this countable ordered according to the given sort order?
    `default boolean` | `isStrictlySorted(java.util.Comparator<? super T> order)` Is this countable strictly ordered according to the given sort order?
    `default T` | `last()` Get the last element.
    `default T` | `lastOrNull()` Get the last element, or `null` if this countable is empty.
    `default <K> Dict<K,T>` | `mappingBy(boolean firstWins, java.util.function.Function<? super T,? extends K> keyExtractor)` Create a mapping of a key extracted from each element to the element itself.
    `default <K,V> Dict<K,V>` | `mappingBy(boolean firstWins, java.util.function.Function<? super T,? extends K> keyExtractor, java.util.function.Function<? super T,? extends V> valueMapper)` Create a mapping of a key extracted from each element to the element itself.
    `default java.util.Optional<T>` | `optFirst()` Get the first element as an Optional.
    `static <E> Countable<E>` | `optional(E optionalElement)` Get a countable with a single or no element.
    `default java.util.Optional<T>` | `optLast()` Get the first element as an Optional.
    `static <VV> Indexable<Pair<VV>>` | `orderedCombination(Countable<VV> countable1, Countable<VV> countable2, java.util.Comparator<? super VV> order)` Create an indexable of pairs from two countables which is the combination of pairs from both countables when ordered.
    `default java.util.stream.Stream<T>` | `parellelStream()` Create a parallel stream from this countable.
    `static <E> Countable<E>` | `singleton(E singleElement)` Get a countable with a single element.
    `default Indexable<T>` | `sorted(java.util.Comparator<? super T> order)` Get a sorted frozen version of this countable.
    `default java.util.Spliterator<T>` | `spliterator()` Create a spliterator from this countable.
    `default java.util.stream.Stream<T>` | `stream()` Create a stream from this countable.
    `default java.lang.Object[]` | `toArray()` Copy the content of this countable to an array.
    `default T[]` | `toArray(java.lang.Class<T> type)` Copy the elements of this countable into an array of typed objects and return the result.
    `default java.util.ArrayList<T>` | `toList()` Get a list which is the copy of this countable.
    `static java.lang.String` | `toString(Countable<?> countable)` Create a string representation of the given countable.
    `static <E> Countable<E>` | `uniform(E element, int count)` Get a countable which is returning the same element multiple times.
    `default <R> Countable<R>` | `view(java.util.function.Function<? super T,? extends R> mapper)` View this countable as if it has another type.
    `static <E> Countable<E>` | `viewArray(E... elements)` View an array as if it were a countable.
    `static <E> Countable<E>` | `viewArray(E[] elements, int start, int length)` View a part of an array as if it were a countable.
    `static <E> Countable<E>` | `viewCollection(java.util.Collection<? extends E> collection)` View a collection as if it were a countable.
    `static <E,T> Countable<T>` | `viewCollection(java.util.Collection<E> collection, java.util.function.Function<? super E,? extends T> mapper)` Create a read-only view of a collection as if it were a countable of a different type.
    `static <E> Countable<E>` | `viewCollectionN(java.util.Collection<? extends E> collection)` View a collection which is potentially `null` as if it were a countable.
    `static <E,T> Countable<T>` | `viewCollectionN(java.util.Collection<E> collection, java.util.function.Function<? super E,? extends T> mapper)` Create a read-only view of a collection which is possibly `null` as if it were a countable of a different type.
    `default <R,E extends java.lang.Exception> Countable<R>` | `viewFragile(FragileFunction1<? extends R,E,? super T> mapper)` View this countable as if it has another type using a fragile mapping which might throw a checked exception.
    `default Countable<T>` | `withAppendedItem(T item)` Return a view of this countable which has the given item appended.
    `default Countable<T>` | `withPrependedItem(T item)` Return a view of this countable which has the given item prepended.

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

      `forEach, iterator`

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

      `size`

- - ### Field Detail

    - #### EMPTY

          static final Countable<java.lang.Object> EMPTY

      A 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<T> asCollection()

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

    - #### toList

          @NotNull
          default java.util.ArrayList<T> 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 T> collection)

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

    - #### toArray

          @NotNull
          default java.lang.Object[] toArray()

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

    - #### toArray

          @NotNull
          default T[] toArray(@NotNull
                                       java.lang.Class<T> type)

      Copy the elements of this countable into an array of typed objects and return the result.
      Parameters:
        `type` - array element type, has to match the element type of this indexable
      Returns:
        array of objects

    - #### addToArray

          default int addToArray(@NotNull
                                 T[] 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.Function<? super T,? extends R> mapper)

      View this 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

    - #### viewFragile

          @NotNull
          default <R,E extends java.lang.Exception> Countable<R> viewFragile(@NotNull
                                                                                      FragileFunction1<? extends R,E,? super T> mapper)

      View this countable as if it has another type using a fragile mapping which might throw a checked exception.

      The returned countable is evaluated lazily, so the exception might be triggered much later, of even never if the element where the converted does throw an exception is never used.

      If `mapper` is throwing an exception this exception is wrapped into a `WrappedFragileException` which is thrown instead.

      If the resulting countable is only temporarily used, you can wrap its usage with a try-catch construction (see below). If it is returned from your code the only way to make the exception appear early is `freezing` with the price of an internal copy.

      Example of wrapping the usage (assuming that method `Foo foo(Bar)` converts `Foo` objects to `Bar` objects with the occasional `CheckedException` exception):

             try {
               Countable<Bar> bars = // ...
               try {
                 Countable<Foo> foos = bars.viewFragile(bar -> foo(bar));
                 // use foos only inside this block or
             //  return foos.frozen();
                 // to trigger possible exceptions inside this block.
               } catch(WrappedFragileException x) {
                 x.rethrow(CheckedException.class); // this will throw the caught exception
                 // throw new RuntimeException("Never will reach here!");
               }
             }

      Type Parameters:
        `R` - target type of the elements of the returned countable
        `E` - possible exception thrown by `mapper`
      Parameters:
        `mapper` - mapper from incoming to outgoing objects which might throw an exception
      Returns:
        lazy view of this countable which will seem to contain target type elements

    - #### filtered

          @NotNull
          default java.lang.Iterable<T> filtered(@NotNull
                                                          java.util.function.Predicate<? super T> filter)

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

    - #### filterToCountable

          @NotNull
          default Countable<T> filterToCountable(@NotNull
                                                          java.util.function.Predicate<? super T> filter)

      Get a countable which contains elements from this countable which fulfill a given filter condition. In difference to `filtered(Predicate)` this will create an independent copy.
      Parameters:
        `filter` - filter conditian used to select elements of the returned indexable
      Returns:
        countable with all elements from this countable which fulfill the filter condition, in the same sequence as they appear in this countable

    - #### filteredToIndexable

          @NotNull
          default Indexable<T> filteredToIndexable(@NotNull
                                                            java.util.function.Predicate<? super T> filter)

      Get an indexable which contains elements from this countable which fulfill a given filter. In difference to `filtered(Predicate)` this will create an independent copy.
      Parameters:
        `filter` - filter used to select elements of the returned indexable
      Returns:
        indexable with all elements from this countable which fulfill the filter, in the same sequence as they appear in this indexable, already frozen

    - #### forEachFragile

          default <E extends java.lang.Exception> void forEachFragile(@NotNull
                                                                      FragileProcedure1<E,? super T> consumer)
                                                               throws E extends java.lang.Exception

      Apply a fragile consumer to each element of this countable.
      Type Parameters:
        `E` - exception which the consumer might throw
      Parameters:
        `consumer` - fragile consumer which might throw an exception
      Throws:
        `E` - forwarded exception of the consumer
        `E extends java.lang.Exception`

    - #### foldLeft

          default <V> V foldLeft(V initialValue,
                                 @NotNull
                                 java.util.function.BiFunction<? super V,? super T,? extends V> folder)

      Calculate a value from this countable by reapplying a 2-argument function for each element, with the result of the latest application and the current element.
      Type Parameters:
        `V` - result value type
      Parameters:
        `initialValue` - initial start value used with the first element
        `folder` - folding function, will receive the accumulated value as its first argument and the current element as its second argument
      Returns:
        accumulated value

    - #### frozen

          @NotNull
          default Indexable<T> 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 method copies the current state of this countable into an unmodifiable state, and returns a Countable which is stable in size and will return always the same elements. Beware: it is still possible that any element itself changes when the elements are mutable. Use `frozen(Function, boolean)` to take care of this.

      Calling `frozen()` again on the returned object will just return the object itself, so you can safely call this method more than once.

      Returns:
        frozen indexable version of this countable

    - #### freeze

          @NotNull
          static <TT> Indexable<TT> freeze(@NotNull
                                                    Countable<? extends TT> countable)

      Freeze a countable to an indexable. In difference to `frozen()` this method allows to change the element type to one of its super types. As the view is read-only this is not a problem.
      Type Parameters:
        `TT` - element type of returned countable
      Parameters:
        `countable` - countable to freeze
      Returns:
        frozen version of the countable

    - #### sorted

          @NotNull
          default Indexable<T> sorted(@NotNull
                                               java.util.Comparator<? super T> 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. Beware: it is still possible that any element itself changes when the elements are mutable. Use `frozen(Function, boolean)` and sort afterwards to take care of this.

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

    - #### isSorted

          default boolean isSorted(@NotNull
                                   java.util.Comparator<? super T> order)

      Is this countable ordered according to the given sort order? This method accepts equal elements and assumes them ordered. See `isStrictlySorted(Comparator)` 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
                                           java.util.Comparator<? super T> order)

      Is this countable strictly ordered according to the given sort order? This method does consider equal elements unordered. See `isSorted(Comparator)` 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 Indexable<T> frozen(@NotNull
                                               java.util.function.Function<? super T,? extends T> elementCloner,
                                               boolean cloneOnGet)

      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.

      Parameters:
        `elementCloner` - cloner called for each element of this countable to create the same-position element in the frozen countable
        `cloneOnGet` - make the returned countable clone an element each time it is requested? If `true` elements inside the returned countable will be protected from mutation with the price of creating a copy on each request.
      Returns:
        frozen indexable version of this Countable

    - #### first

          default T first()

      Get the first element.
      Returns:
        first element in this countable
      Throws:
        `java.util.NoSuchElementException` - if this countable is empty
      See Also:
        `firstOrNull()`, `optFirst()`

    - #### firstOrNull

          @Nullable
          default T firstOrNull()

      Get the first element, or `null` if this countable is empty. Note that this method is dubious for countables which could contain `null` elements.
      Returns:
        first element, or `null` if this countable is empty
      See Also:
        `first()`, `optFirst()`

    - #### optFirst

          @NotNull
          default java.util.Optional<T> optFirst()

      Get the first element as an Optional. Note that this method will throw a `NullPointerException` if the first element is `null` elements.
      Returns:
        optional, empty if this countable is empty
      Throws:
        `java.lang.NullPointerException` - if first element is `null`
      See Also:
        `first()`, `firstOrNull()`

    - #### last

          default T last()

      Get the last element. In the base implementation iterates over all elements in this countable to reach the last element.
      Returns:
        last element in this countable
      See Also:
        `lastOrNull()`, `optLast()`

    - #### lastOrNull

          default T lastOrNull()

      Get the last element, or `null` if this countable is empty. In the base implementation iterates over all elements in this countable to reach the last element. Note that this method is dubious for countables which could contain `null` elements.
      Returns:
        last element, or `null` if this countable is empty
      See Also:
        `last()`, `optLast()`

    - #### optLast

          @NotNull
          default java.util.Optional<T> optLast()

      Get the first element as an Optional. In the base implementation iterates over all elements in this countable to reach the last element. Note that this method will throw a `NullPointerException` if the last element is `null` elements.
      Returns:
        optional, empty if this countable is empty
      Throws:
        `java.lang.NullPointerException` - if last element is `null`
      See Also:
        `last()`, `lastOrNull()`

    - #### withPrependedItem

          @NotNull
          default Countable<T> withPrependedItem(T item)

      Return a view of this countable which has the given item prepended.
      Parameters:
        `item` - item to appear first when iterating
      Returns:
        a view of this countable with the given item prepended

    - #### withAppendedItem

          @NotNull
          default Countable<T> withAppendedItem(T item)

      Return a view of this countable which has the given item appended.
      Parameters:
        `item` - item to appear last when iterating
      Returns:
        a view of this countable with the given item appended

    - #### containsEq

          default boolean containsEq(T elem)

      Is the given element contained? This uses `Objects.deepEquals(Object, Object)` for checking whether an element is contained.
      Parameters:
        `elem` - element to check for
      Returns:
        `true` if the element is contained in this countable
        `false` if not
      See Also:
        `containsRef(Object)`

    - #### containsRef

          default boolean containsRef(T elem)

      Is the given element contained? This checks for an identical reference.
      Parameters:
        `elem` - element to check for
      Returns:
        `true` if the element is contained in this countable
        `false` if not
      See Also:
        `containsEq(Object)`

    - #### hasAny

          default boolean hasAny(@NotNull
                                 java.util.function.Predicate<? super T> check)

      Check if any element fulfills a given predicate. This uses shortcut evaluation and will return on the first hit.
      Parameters:
        `check` - predicate to check
      Returns:
        `true` if the predicate tested `true` on any element
        `false` if it tested `false` on all elements

    - #### getAny

          @Nullable
          default T getAny(@NotNull
                                     java.util.function.Predicate<? super T> check)

      Get the first element which fulfills the predicate.
      Parameters:
        `check` - check for identifying matches
      Returns:
        first match found

    - #### hasAll

          default boolean hasAll(@NotNull
                                 java.util.function.Predicate<? super T> check)

      Check if all elements fulfill a given predicate. This uses shortcut evaluation and will return on the first miss.

      Note that as this basically checks for misses an empty countable will return always return `true`. If this is an issue, add a check for emptiness.

      Parameters:
        `check` - predicate to check
      Returns:
        `true` if the predicate tested `true` on all element
        `false` if it tested `false` on any element

    - #### groupingBy

          @NotNull
          default <K> Dict<K,Indexable<T>> groupingBy(@NotNull
                                                               java.util.function.Function<? super T,? extends K> keyExtractor)

      Create a mapping of a key extracted from each element to groups of elements which belongs to this key.
      Type Parameters:
        `K` - grouping key type
      Parameters:
        `keyExtractor` - key extractor which defines the key for a given element in this countable
      Returns:
        mapping of keys to groups of elements belonging to this key. It is recommended to apply `Dict.frozen()` to the result if it is not temporary.

    - #### groupingBy

          @NotNull
          default <K,V> Dict<K,Indexable<V>> groupingBy(@NotNull
                                                                 java.util.function.Function<? super T,? extends K> keyExtractor,
                                                                 @NotNull
                                                                 java.util.function.Function<? super T,? extends V> valueMapper)

      Create a mapping of a key extracted from each element to groups of elements which belongs to this key.
      Type Parameters:
        `K` - grouping key type
        `V` - value type of the resulting groups
      Parameters:
        `keyExtractor` - key extractor which defines the key for a given element in this countable
        `valueMapper` - mapper which converts the elements of this countable to the element type of the returned groups
      Returns:
        mapping of keys to groups of values belonging to this key. It is recommended to apply `Dict.frozen()` to the result if it is not temporary.

    - #### mappingBy

          @NotNull
          default <K> Dict<K,T> mappingBy(boolean firstWins,
                                                   @NotNull
                                                   java.util.function.Function<? super T,? extends K> keyExtractor)

      Create a mapping of a key extracted from each element to the element itself. If two elements resolve to the same key, parameter `firstWins` defines whether the first is kept or overwritten.

      Use `groupingBy(Function)` if you want to keep all values.

      Type Parameters:
        `K` - key type
      Parameters:
        `firstWins` - if `true` the first element which resolves to a given key is kept, all others are discarded, if `false` the last element which resolves to a key is kept
        `keyExtractor` - key extractor which defines the key for a given element in this countable
      Returns:
        mapping of keys to associated elements

    - #### mappingBy

          @NotNull
          default <K,V> Dict<K,V> mappingBy(boolean firstWins,
                                                     @NotNull
                                                     java.util.function.Function<? super T,? extends K> keyExtractor,
                                                     @NotNull
                                                     java.util.function.Function<? super T,? extends V> valueMapper)

      Create a mapping of a key extracted from each element to the element itself. If two elements resolve to the same key, parameter `firstWins` defines whether the first is kept or overwritten.

      Use `groupingBy(Function, Function)` if you want to keep all values.

      Type Parameters:
        `K` - key type
        `V` - value type returned mapping
      Parameters:
        `firstWins` - if `true` the first element which resolves to a given key is kept, all others are discarded, if `false` the last element which resolves to a key is kept
        `keyExtractor` - key extractor which defines the key for a given element in this countable
        `valueMapper` - mapper which converts the elements of this countable to the element type of the returned groups
      Returns:
        mapping of keys to associated elements

    - #### asBase

          @NotNull
          default Countable.Base<T> 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

    - #### equals

          default <E> boolean equals(@NotNull
                                     Countable<E> other,
                                     @NotNull
                                     java.util.function.BiPredicate<? super T,? super E> elementEquals)

      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.

      It's using `equal(Countable, Countable, BiPredicate)` to perform the check and therefore follows its invariants.

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

    - #### spliterator

          @NotNull
          default java.util.Spliterator<T> spliterator()

      Create a spliterator from this countable.
      Specified by:
        `spliterator` in interface `java.lang.Iterable<T>`
      Returns:
        spliterator from this countable

    - #### stream

          @NotNull
          default java.util.stream.Stream<T> stream()

      Create a stream from this countable.
      Returns:
        stream from his countable

    - #### parellelStream

          @NotNull
          default java.util.stream.Stream<T> parellelStream()

      Create a parallel stream from this countable.
      Returns:
        parallel stream from this countable

    - #### viewCollection

          @NotNull
          static <E> Countable<E> viewCollection(@NotNull
                                                          java.util.Collection<? extends E> 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));

      Type Parameters:
        `E` - element type of the returned countable, which because of the read-only nature of this interface can be any super-type of the collection's element type
      Parameters:
        `collection` - collection to view
      Returns:
        countable view of the given `collection`

    - #### viewCollectionN

          @NotNull
          static <E> Countable<E> viewCollectionN(@Nullable
                                                           java.util.Collection<? extends E> 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
      Type Parameters:
        `E` - element type of the returned countable, which because of the read-only nature of this interface can be any super-type of the collection's element type
      Parameters:
        `collection` - collection to view
      Returns:
        countable view of the given `collection`, `empty` if `collection` is `null`

    - #### viewCollection

          @NotNull
          static <E,T> Countable<T> viewCollection(@NotNull
                                                            java.util.Collection<E> collection,
                                                            @NotNull
                                                            java.util.function.Function<? super E,? extends T> mapper)

      Create a read-only view of a collection as if it were a countable of a different type. This creates read-only access to the underlying collection which represents its elements in a different way.

      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), mapper);

      or call frozen() on the returned countable.
      Type Parameters:
        `E` - element type of the incoming collection
        `T` - element type of the returned countable
      Parameters:
        `collection` - collection to view
        `mapper` - mapper which turns the elements of the incoming collection into the elements of the countable
      Returns:
        countable view of the given `collection`
      See Also:
        `viewCollection(Collection)`

    - #### viewCollectionN

          @NotNull
          static <E,T> Countable<T> viewCollectionN(@Nullable
                                                             java.util.Collection<E> collection,
                                                             @NotNull
                                                             java.util.function.Function<? super E,? extends T> mapper)

      Create a read-only view of a collection which is possibly `null` as if it were a countable of a different type. This creates a read-only access to the underlying collection which represents its elements in a different way. Besides of the handling of `null` this behaves the same as `viewCollection(Collection, Function)`, for `null` this returns the empty countable.
      Type Parameters:
        `E` - element type of the incoming collection
        `T` - element type of the returned countable
      Parameters:
        `collection` - collection to view
        `mapper` - mapper which turns the elements of the incoming collection into the elements of the countable
      Returns:
        countable view of the given `collection`, empty for `null`

    - #### viewArray

          @NotNull
           @SafeVarargs
          static <E> Countable<E> viewArray(@NotNull
                                                                   E... elements)

      View an array as if it were a countable.

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

      >      Countable.viewCollection(array.clone());

      Type Parameters:
        `E` - array element type, also element type of returned countable
      Parameters:
        `elements` - array of elements
      Returns:
        countable view of the given array

    - #### viewArray

          @NotNull
          static <E> Countable<E> viewArray(@NotNull
                                                     E[] elements,
                                                     int start,
                                                     int length)

      View a part of an array as if it were a countable.

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

      >      Countable.viewCollection(Arrays.copyOfRange(elements, start, start + length));

      Type Parameters:
        `E` - array element type, also element type of returned countable
      Parameters:
        `elements` - array of elements
        `start` - start index of represented elements of array
        `length` - number of elements represented from array
      Returns:
        countable view of the given part of the array

    - #### downCast

          @NotNull
          static <E> Countable<E> downCast(@NotNull
                                                    Countable<? extends E> countable)

      Downcast a countable of a given type so that it appears at a countable of a super type. This method does nothing but return its argument, but using it keeps the compiler happy. So it is so cheap that the JIT might even remove it. Downcasting countables is no problem, as they don't allow adding new elements.

      Example:

      >      Countable<String> a = Countable.viewArray("a", "b", "c");
      >      Countable<Object> b = Countable.downCast(a); // no compiler warning here
      >      assert a == b;

      Type Parameters:
        `E` - target type of returned countable
      Parameters:
        `countable` - countable to be downcasted, needs to have a tyoe which extends or implements `<E>`
      Returns:
        `countable`, but using a different element type

    - #### empty

          @NotNull
          static <E> Countable<E> empty()

      Get an empty countable. This is often preferable as a return result to indicate nothing instead of returning `null`.
      Type Parameters:
        `E` - element type of the returned empty countable
      Returns:
        empty countable

    - #### singleton

          @NotNull
          static <E> Countable<E> singleton(E singleElement)

      Get a countable with a single element.
      Type Parameters:
        `E` - element type of this countable
      Parameters:
        `singleElement` - single element of this countable
      Returns:
        countable of size 1 with the given element

    - #### optional

          @NotNull
          static <E> Countable<E> optional(@Nullable
                                                    E optionalElement)

      Get a countable with a single or no element.
      Type Parameters:
        `E` - element type
      Parameters:
        `optionalElement` - optional element
      Returns:
        countable with size 1 with the given element if it is not `null`, or an empty countable if it is `null`

    - #### fromOptional

          @NotNull
          static <E> Countable<E> fromOptional(@NotNull
                                                        java.util.Optional<E> optional)

      Convert a standard Optional to a Countable with either one or no element.
      Type Parameters:
        `E` - optional/countable type
      Parameters:
        `optional` - optional to convert to countable
      Returns:
        countable with either 1 element (if the optional has an element) or 0 elements (if the optional has no element)

    - #### uniform

          @NotNull
          static <E> Countable<E> uniform(@NotNull
                                                   E element,
                                                   int count)

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

    - #### combined

          @NotNull
           @SafeVarargs
          static <E> Countable<E> combined(@NotNull
                                                                  Countable<? extends E>... parts)

      Combine several countables into one.
      Type Parameters:
        `E` - element type of resulting countable
      Parameters:
        `parts` - countables to be combined
      Returns:
        countable which is the combination of the parts, iterating will iterate over all elements as expected

    - #### combined

          @NotNull
          static <E> Countable<E> combined(@NotNull
                                                    Countable<? extends Countable<? extends E>> parts)

      Combine several countables into one.
      Type Parameters:
        `E` - element type of resulting countable
      Parameters:
        `parts` - countables to be combined
      Returns:
        countable which is the combination of the parts, iterating will iterate over all elements as expected

    - #### orderedCombination

          @NotNull
          static <VV> Indexable<Pair<VV>> orderedCombination(@NotNull
                                                                      Countable<VV> countable1,
                                                                      @NotNull
                                                                      Countable<VV> countable2,
                                                                      @NotNull
                                                                      java.util.Comparator<? super VV> order)

      Create an indexable of pairs from two countables which is the combination of pairs from both countables when ordered. Each pair will either contain a combination of elements from the first and second countable if both have are considered equal according to the order, or of a pair with a `null` `OrderedPair.first` entry if an element from the second countable does not have a counterpart, or a pair with a `null` `OrderedPair.second` entry if a given value from the first countable does not have a counterpart.
      Type Parameters:
        `VV` - value type
      Parameters:
        `countable1` - first countable
        `countable2` - second countable
        `order` - order applied to the countables
      Returns:
        ordered indexable of pairs with matching counterparts from both countables, or one entry being `null` for unmatched entries

    - #### equal

          static <E1,E2> boolean equal(@NotNull
                                       Countable<E1> countable1,
                                       @NotNull
                                       Countable<E2> countable2,
                                       @NotNull
                                       java.util.function.BiPredicate<? super E1,? super E2> equalityChecker)

      Are two countables equal?

      Equality is complex, because it depends. This equality check for two countables allows to define how elements are compared. Regardless from that it there are 2 invariants:

      1. Both countables are equal if they refer to the same object.
      2. Both countables are not equal if they have different sizes.
      It is possible to compare two countables with different element types.
      Type Parameters:
        `E1` - element type of first countable
        `E2` - element type of second countable
      Parameters:
        `countable1` - first countable
        `countable2` - second countable
        `equalityChecker` - checker for equality of both objects
      Returns:
        `true` if both countables contain the same values in the same sequence
        `false` if sizes or values differ

    - #### toString

          @NotNull
          static java.lang.String toString(@NotNull
                                                    Countable<?> countable)

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