T
- object type of this countablepublic interface Countable<T> extends java.lang.Iterable<T>, Sizeable
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.
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() . |
Modifier and Type | Field and Description |
---|---|
static Countable<java.lang.Object> |
EMPTY
Basic implementation of an empty countable
Don't use this, use
empty() . |
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 <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> |
forEachFragile(FragileProcedure1<E,? super T> consumer)
Apply a fragile consumer to each element of this countable.
|
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 <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 <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.
|
static <E> Countable<E> |
optional(E optionalElement)
Get a countable with a single or no element.
|
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.
|
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.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 boolean isEmpty()
Sizeable.size()
will return 0
.
This default implementation just checks for Sizeable.size()
returning 0
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.
@NotNull default java.util.Collection<T> asCollection()
Collection
view of this countable@NotNull default java.util.ArrayList<T> toList()
default void addAllTo(@NotNull java.util.Collection<? super T> collection)
collection
- collection where all entries are added@NotNull default java.lang.Object[] toArray()
@NotNull default T[] toArray(@NotNull java.lang.Class<T> type)
type
- array element type, has to match the element type of this indexabledefault int addToArray(@NotNull T[] array, int arrayPos)
array
- array where the content is addedarrayPos
- start position in hte array where the content is added@NotNull default <R> Countable<R> view(@NotNull java.util.function.Function<? super T,? extends R> mapper)
R
- resulting element typemapper
- converter from elements of this countable to elements of the returned countable@NotNull default java.lang.Iterable<T> filtered(@NotNull java.util.function.Predicate<? super T> filter)
filter
- check which defines the elements which are included in the returned Iterbble
.filter
accepts@NotNull default Countable<T> filterToCountable(@NotNull java.util.function.Predicate<? super T> filter)
filtered(Predicate)
this
will create an independent copy.filter
- filter conditian used to select elements of the returned indexable@NotNull default Indexable<T> filteredToIndexable(@NotNull java.util.function.Predicate<? super T> filter)
filtered(Predicate)
this
will create an independent copy.filter
- filter used to select elements of the returned indexabledefault <E extends java.lang.Exception> void forEachFragile(@NotNull FragileProcedure1<E,? super T> consumer) throws E extends java.lang.Exception
E
- exception which the consumer might throwconsumer
- fragile consumer which might throw an exceptionE
- forwarded exception of the consumerE extends java.lang.Exception
default <V> V foldLeft(V initialValue, @NotNull java.util.function.BiFunction<? super V,? super T,? extends V> folder)
V
- result value typeinitialValue
- initial start value used with the first elementfolder
- folding function, will receive the accumulated value as its first argument
and the current element as its second argument@NotNull default Indexable<T> frozen()
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.
@NotNull default Indexable<T> sorted(@NotNull java.util.Comparator<? super T> order)
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.
order
- ordering condition for the returned indexabledefault boolean isSorted(@NotNull java.util.Comparator<? super T> order)
isStrictlySorted(Comparator)
for a check which does not accept that.
Empty or 1-element countables will always return true
.order
- order which is checkedtrue
if the elements in this countable are ordered considering the given order
false
if notdefault boolean isStrictlySorted(@NotNull java.util.Comparator<? super T> order)
isSorted(Comparator)
for a check which is more relaxed.
Empty or 1-element countables will always return true
.order
- order which is checkedtrue
if the elements in this countable are ordered considering the given order
false
if not@NotNull default Indexable<T> frozen(@NotNull java.util.function.Function<? super T,? extends T> elementCloner, boolean cloneOnGet)
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.
elementCloner
- cloner called for each element of this countable to create
the same-position element in the frozen countablecloneOnGet
- 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.default T first()
java.util.NoSuchElementException
- if this countable is emptydefault T last()
default boolean containsEq(T elem)
Objects.deepEquals(Object, Object)
for checking whether an
element is contained.elem
- element to check fortrue
if the element is contained in this countablefalse
if notcontainsRef(Object)
default boolean containsRef(T elem)
elem
- element to check fortrue
if the element is contained in this countablefalse
if notcontainsEq(Object)
default boolean hasAny(@NotNull java.util.function.Predicate<? super T> check)
check
- predicate to checktrue
if the predicate tested true
on any elementfalse
if it tested false
on all elementsdefault boolean hasAll(@NotNull java.util.function.Predicate<? super T> check)
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.
check
- predicate to checktrue
if the predicate tested true
on all elementfalse
if it tested false
on any element@NotNull default <K> Dict<K,Indexable<T>> groupingBy(@NotNull java.util.function.Function<? super T,? extends K> keyExtractor)
K
- grouping key typekeyExtractor
- key extractor which defines the key for a given element in this countableDict.frozen()
to the result if it is not temporary.@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)
K
- grouping key typeV
- value type of the resulting groupskeyExtractor
- key extractor which defines the key for a given element in this countablevalueMapper
- mapper which converts the elements of this countable to the element type of the
returned groupsDict.frozen()
to the result if it is not temporary.@NotNull default <K> Dict<K,T> mappingBy(boolean firstWins, @NotNull java.util.function.Function<? super T,? extends K> keyExtractor)
firstWins
defines
whether the first is kept or overwritten.
Use groupingBy(Function)
if you want to keep all values.
K
- key typefirstWins
- 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 keptkeyExtractor
- key extractor which defines the key for a given element in this countable@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)
firstWins
defines
whether the first is kept or overwritten.
Use groupingBy(Function, Function)
if you want to keep all values.
K
- key typeV
- value type returned mappingfirstWins
- 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 keptkeyExtractor
- key extractor which defines the key for a given element in this countablevalueMapper
- mapper which converts the elements of this countable to the element type of the
returned groups@NotNull default Countable.Base<T> asBase()
Object.equals(Object)
, Object.hashCode()
,
and Object.toString()
.default <E> boolean equals(@NotNull Countable<E> other, @NotNull java.util.function.BiPredicate<? super T,? super E> elementEquals)
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.
E
- element type of other countableother
- other countableelementEquals
- check for element equalitytrue
if this and the other countable are considered equal regarding the given element checkfalse
if not@NotNull static <E> Countable<E> viewCollection(@NotNull java.util.Collection<? extends E> 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));
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 typecollection
- collection to viewcollection
@NotNull static <E> Countable<E> viewCollectionN(@Nullable java.util.Collection<? extends E> collection)
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:
or call frozen() on the returned countableCountable.viewCollection(new ArrayList<>(collection));
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 typecollection
- collection to viewcollection
, empty
if collection
is null
@NotNull static <E,T> Countable<T> viewCollection(@NotNull java.util.Collection<E> collection, @NotNull java.util.function.Function<? super E,? extends T> mapper)
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:
or call frozen() on the returned countable.Countable.viewCollection(new ArrayList<>(collection), mapper);
E
- element type of the incoming collectionT
- element type of the returned countablecollection
- collection to viewmapper
- mapper which turns the elements of the incoming collection into
the elements of the countablecollection
viewCollection(Collection)
@NotNull static <E,T> Countable<T> viewCollectionN(@Nullable java.util.Collection<E> collection, @NotNull java.util.function.Function<? super E,? extends T> mapper)
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.E
- element type of the incoming collectionT
- element type of the returned countablecollection
- collection to viewmapper
- mapper which turns the elements of the incoming collection into
the elements of the countablecollection
, empty for null
@NotNull @SafeVarargs static <E> Countable<E> viewArray(@NotNull E... elements)
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());
E
- array element type, also element type of returned countableelements
- array of elements@NotNull static <E> Countable<E> viewArray(@NotNull E[] elements, int start, int length)
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));
E
- array element type, also element type of returned countableelements
- array of elementsstart
- start index of represented elements of arraylength
- number of elements represented from array@NotNull static <E> Countable<E> downCast(@NotNull Countable<? extends E> countable)
E
- target type of returned countablecountable
- coubtable to be downcasted, needs to have a tyoe which extends or implements <E>
countable
, but using a different element type@NotNull static <E> Countable<E> empty()
null
.E
- element type of the returned empty countable@NotNull static <E> Countable<E> singleton(@NotNull E singleElement)
E
- element type of this countablesingleElement
- single element of this countable@NotNull static <E> Countable<E> optional(@Nullable E optionalElement)
E
- element typeoptionalElement
- optional elementnull
,
or an empty countable if it is null
@NotNull static <E> Countable<E> fromOptional(@NotNull java.util.Optional<E> optional)
E
- optional/countable typeoptional
- optional to convert to countable@NotNull static <E> Countable<E> uniform(@NotNull E element, int count)
E
- element typeelement
- element returned from this countable on each next()
call of its iteratorcount
- number of times the same element is returned from the iterator, must not be negativeelement
count
times during iteration@NotNull @SafeVarargs static <E> Countable<E> combined(@NotNull Countable<? extends E>... parts)
E
- element type of resulting countableparts
- countables to be combined@NotNull static <E> Countable<E> combined(@NotNull Countable<? extends Countable<? extends E>> parts)
E
- element type of resulting countableparts
- countables to be combined@NotNull static <VV> Indexable<Pair<VV>> orderedCombination(@NotNull Countable<VV> countable1, @NotNull Countable<VV> countable2, @NotNull java.util.Comparator<? super VV> order)
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.VV
- value typecountable1
- first countablecountable2
- second countableorder
- order applied to the countablesnull
for unmatched entriesstatic <E1,E2> boolean equal(@NotNull Countable<E1> countable1, @NotNull Countable<E2> countable2, @NotNull java.util.function.BiPredicate<? super E1,? super E2> equalityChecker)
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:
E1
- element type of first countableE2
- element type of second countablecountable1
- first countablecountable2
- second countableequalityChecker
- checker for equality of both objectstrue
if both countables contain the same values in the same sequencefalse
if sizes or values differ