ix.Ix Maven / Gradle / Ivy
Show all versions of ixjava Show documentation
/*
* Copyright 2011-2016 David Karnok
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ix;
import java.util.*;
import java.util.concurrent.Callable;
/**
* Base class and entry point for fluent Iterables.
*
* All operators tolerate {@code null} elements.
*
* The Iterables have to be run in a single-threaded manner and none of
* the participating operators expect or support concurrency.
* @param the value type
* @since 1.0
*/
public abstract class Ix implements Iterable {
/**
* Emits all characters from the given CharSequence as integer values.
*
* The result's iterator() doesn't support remove().
* @param cs the source character sequence, not null
* @return the new Ix instance
* @throws NullPointerException if cs is null
* @since 1.0
*/
public static Ix characters(CharSequence cs) {
return new IxCharacters(cs, 0, cs.length());
}
/**
* Emits a range of characters from the given CharSequence as integer values.
*
* The result's iterator() doesn't support remove().
* @param cs the source character sequence, not null
* @param start the start character index, inclusive, non-negative
* @param end the end character index, exclusive, non-negative
* @return the new Ix instance
* @throws NullPointerException if cs is null
* @throws IndexOutOfBoundsException if start is out of range [0, cs.length]
* @since 1.0
*/
public static Ix characters(CharSequence cs, int start, int end) {
int len = cs.length();
if (start < 0 || end < 0 || start > len || end > len) {
throw new IndexOutOfBoundsException("start=" + start + ", end=" + end + ", length=" + len);
}
return new IxCharacters(cs, start, end);
}
/**
* Concatenates the elements of Iterable sources, provided as an Iterable itself, sequentially.
*
* The result's iterator() forwards the remove() calls to the current iterator.
*
* Note that merge and concat operations are the same in the Iterable world.
* @param the common base type
* @param sources the Iterable sequence of source Iterables
* @return the new Ix instance
* @throws NullPointerException if sources is null
* @since 1.0
* @see #merge(Iterable)
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static Ix concat(Iterable extends Iterable extends T>> sources) {
return new IxFlattenIterable, T>(
(Iterable)nullCheck(sources, "sources is null"),
IdentityHelper.>instance());
}
/**
* Concatenates the elements of two Iterable sources sequentially
*
* The result's iterator() forwards the remove() calls to the current iterator.
*
* Note that merge and concat operations are the same in the Iterable world.
* @param the value type
* @param source1 the first source, not null
* @param source2 the second source, not null
* @return the new Iterable source
* @throws NullPointerException if any of the sources is null
* @since 1.0
*/
@SuppressWarnings("unchecked")
public static Ix concat(Iterable extends T> source1, Iterable extends T> source2) {
return concatArray(nullCheck(source1, "source1 is null"), nullCheck(source2, "source2 is null"));
}
/**
* Concatenates the elements of three Iterable sources sequentially
*
* The result's iterator() forwards the remove() calls to the current iterator.
*
* Note that merge and concat operations are the same in the Iterable world.
* @param the value type
* @param source1 the first source, not null
* @param source2 the second source, not null
* @param source3 the third source, not null
* @return the new Iterable source
* @throws NullPointerException if any of the sources is null
* @since 1.0
*/
@SuppressWarnings("unchecked")
public static Ix concat(Iterable extends T> source1, Iterable extends T> source2,
Iterable extends T> source3) {
return concatArray(nullCheck(source1, "source1 is null"),
nullCheck(source2, "source2 is null"), nullCheck(source3, "source3 is null"));
}
/**
* Concatenates the elements of three Iterable sources sequentially
*
* The result's iterator() forwards the remove() calls to the current iterator.
*
* Note that merge and concat operations are the same in the Iterable world.
* @param the value type
* @param source1 the first source, not null
* @param source2 the second source, not null
* @param source3 the third source, not null
* @param source4 the fourth source, not null
* @return the new Iterable source
* @throws NullPointerException if any of the sources is null
* @since 1.0
*/
@SuppressWarnings("unchecked")
public static Ix concat(Iterable extends T> source1, Iterable extends T> source2,
Iterable extends T> source3, Iterable extends T> source4) {
return concatArray(nullCheck(source1, "source1 is null"), nullCheck(source2, "source2 is null"),
nullCheck(source3, "source3 is null"), nullCheck(source4, "source4 is null"));
}
/**
* Concatenates the elements of Iterable sources, provided as an array, sequentially.
*
* The result's iterator() forwards the remove() calls to the current iterator.
*
* Note that merge and concat operations are the same in the Iterable world.
* @param the common base type
* @param sources the array of source Iterables
* @return the new Ix instance
* @throws NullPointerException if sources is null
* @since 1.0
* @see #mergeArray(Iterable...)
*/
@SuppressWarnings("unchecked")
public static Ix concatArray(Iterable extends T>... sources) {
int n = sources.length;
if (n == 0) {
return empty();
}
if (n == 1) {
return from((Iterable)sources[0]);
}
return new IxFlattenArrayIterable((Iterable[])sources);
}
/**
* Defers the generation of the actual Iterable till the iterator() is called on
* the resulting Ix.
*
* The result's iterator() forwards the remove() calls to the generated Iterable's Iterator.
* @param the value type
* @param factory the function that returns an Iterable when the resulting Ix.iterator() is called
* @return the new Ix source
* @throws NullPointerException if factory is null
* @since 1.0
*/
public static Ix defer(IxSupplier extends Iterable extends T>> factory) {
return new IxDefer(nullCheck(factory, "factory is null"));
}
/**
* No elements are emitted.
*
* The result's iterator() doesn't support remove().
* @param the value type
* @return the new Ix instance
* @since 1.0
*/
public static Ix empty() {
return IxEmpty.instance();
}
/**
* Wraps the given Iterable source into an Ix instance (if
* not already an Ix subclass).
*
* The result's iterator() forwards the remove() calls to the source's
* iterator().
* @param the value type
* @param source the Iterable to wrap, not null
* @return the new Ix instance
* @throws NullPointerException if source is null
* @since 1.0
*/
public static Ix from(Iterable source) {
if (source instanceof Ix) {
return (Ix)source;
}
return new IxWrapper(nullCheck(source, "source"));
}
/**
* Emits all the elements of the given array.
*
* The result's iterator() doesn't support remove().
* @param the value type
* @param values the array of values, not null
* @return the new Ix instance
* @throws NullPointerException if values is null
* @since 1.0
*/
public static Ix fromArray(T... values) {
int n = values.length;
if (n == 0) {
return empty();
}
if (n == 1) {
return just(values[0]);
}
return new IxFromArray(0, values.length, values);
}
/**
* Emits a range of elements from the given array.
*
* The result's iterator() doesn't support remove().
* @param the value type
* @param start the staring index, inclusive, non-negative
* @param end the end index, exclusive, non-negative
* @param values the array of values
* @return the new Ix instance
* @throws NullPointerException if values is null
* @throws IndexOutOfBoundsException if either start or end are not in [0, values.length]
* @since 1.0
*/
public static Ix fromArrayRange(int start, int end, T... values) {
if (start < 0 || end < 0 || start > values.length || end > values.length) {
throw new IndexOutOfBoundsException("start=" + start + ", end=" + end + ", length=" + values.length);
}
return new IxFromArray(start, end, values);
}
/**
* Generates a sequence of values via a generic indexed for-loop style construct;
* the index starts with the given seed, checked via a condition (to terminate),
* generated from the index via the selector and then a new index is generated via next.
*
* The result's iterator() doesn't support remove().
* @param the index value type
* @param the result value type
* @param seed the initial value of the index
* @param condition the receives the current index (before selector is called) and if it
* returns false, the sequence terminates
* @param next the function that receives the current index and returns the next index
* @param selector the function that receives the current index and returns the value
* to be emitted.
* @return the new Ix instance
* @throws NullPointerException if condition, next or selector is null
* @since 1.0
*/
public static Ix forloop(T seed, IxPredicate super T> condition,
IxFunction super T, ? extends T> next,
IxFunction super T, ? extends R> selector) {
return new IxForloop(seed, nullCheck(condition, "condition is null"),
nullCheck(selector, "selector is null"), nullCheck(next, "next is null"));
}
/**
* Calls the given action to generate a value or terminate whenever the next()
* is called on the resulting Ix.iterator().
*
* The result's iterator() doesn't support remove().
*
* The action may call {@code onNext} at most once to signal the next value per action invocation.
* The {@code onCompleted} should be called to indicate no further values will be generated (may be
* called with an onNext in the same action invocation). Calling {@code onError} will immediately
* throw the given exception (as is if it's a RuntimeException or Error; or wrapped into a RuntimeException).
* @param the value type
* @param nextSupplier the action called with an IxEmitter API to receive value, not null
* @return the new Ix instance
* @throws NullPointerException if nextSupplier is null
* @since 1.0
*/
public static Ix generate(IxConsumer> nextSupplier) {
return new IxGenerateStateless(nullCheck(nextSupplier, "nextSupplier is null"));
}
/**
* Calls the given function (with per-iterator state) to generate a value or terminate
* whenever the next() is called on the resulting Ix.iterator().
*
* The result's iterator() doesn't support remove().
*
* The action may call {@code onNext} at most once to signal the next value per action invocation.
* The {@code onCompleted} should be called to indicate no further values will be generated (may be
* called with an onNext in the same action invocation). Calling {@code onError} will immediately
* throw the given exception (as is if it's a RuntimeException or Error; or wrapped into a RuntimeException).
* @param the value type
* @param the state type supplied to and returned by the nextSupplier function
* @param stateSupplier the function that returns a state for each invocation of iterator()
* @param nextSupplier the action called with an IxEmitter API to receive value, not null
* @return the new Ix instance
* @throws NullPointerException if stateSupplier or nextSupplier is null
* @since 1.0
*/
public static Ix generate(IxSupplier stateSupplier, IxFunction2, S> nextSupplier) {
return generate(stateSupplier, nextSupplier, IxEmptyAction.instance1());
}
/**
* Calls the given function (with per-iterator state) to generate a value or terminate
* whenever the next() is called on the resulting Ix.iterator().
*
* The result's iterator() doesn't support remove().
*
* The action may call {@code onNext} at most once to signal the next value per action invocation.
* The {@code onCompleted} should be called to indicate no further values will be generated (may be
* called with an onNext in the same action invocation). Calling {@code onError} will immediately
* throw the given exception (as is if it's a RuntimeException or Error; or wrapped into a RuntimeException).
*
* Note that since there is no direct way to cancel an Iterator, the stateDisposer is only invoked
* when the nextSupplier calls a terminal method.
* @param the value type
* @param the state type supplied to and returned by the nextSupplier function
* @param stateSupplier the function that returns a state for each invocation of iterator()
* @param nextSupplier the action called with an IxEmitter API to receive value, not null
* @param stateDisposer the action called when the nextSupplier signals an {@code onError} or {@code onCompleted}.
* @return the new Ix instance
* @throws NullPointerException if stateSupplier, nextSupplier or stateDisposer is null
* @since 1.0
*/
public static Ix generate(IxSupplier stateSupplier, IxFunction2, S> nextSupplier, IxConsumer super S> stateDisposer) {
return new IxGenerate(nullCheck(stateSupplier, "stateSupplier is null"),
nullCheck(nextSupplier, "nextSupplier is null"), nullCheck(stateDisposer, "stateDisposer is null"));
}
/**
* Emits a single constant value.
*
* The result's iterator() doesn't support remove().
* @param the value type
* @param value the constant value to emit
* @return the new Ix instance
* @since 1.0
*/
public static Ix just(T value) {
return new IxJust(value);
}
/**
* Concatenates the elements of Iterable sources, provided as an Iterable itself, sequentially.
*
* The result's iterator() forwards the remove() calls to the current iterator.
*
* Note that merge and concat operations are the same in the Iterable world.
* @param the common base type
* @param sources the Iterable sequence of source Iterables
* @return the new Ix instance
* @throws NullPointerException if sources is null
* @since 1.0
* @see #concat(Iterable)
*/
public static Ix merge(Iterable extends Iterable extends T>> sources) {
return concat(sources);
}
/**
* Concatenates the elements of Iterable sources, provided as an array, sequentially.
*
* The result's iterator() forwards the remove() calls to the current iterator.
*
* Note that merge and concat operations are the same in the Iterable world.
* @param the common base type
* @param sources the array of source Iterables
* @return the new Ix instance
* @throws NullPointerException if sources is null
* @since 1.0
* @see #concatArray(Iterable...)
*/
public static Ix mergeArray(Iterable extends T>... sources) {
return concatArray(sources); // concat and merge are the same in the Iterable world
}
/**
* Merges self-comparable items from an Iterable sequence of Iterable sequences, picking
* the smallest item from all those inner Iterables until all sources complete.
* @param the value type
* @param sources the Iterable sequence of Iterables of self-comparable items
* @return the new Ix instance
* @since 1.0
*/
public static > Ix orderedMerge(Iterable extends Iterable extends T>> sources) {
return orderedMerge(sources, SelfComparator.INSTANCE);
}
/**
* Merges items from an Iterable sequence of Iterable sequences, picking
* the smallest item (according to a custom comparator) from all those inner
* Iterables until all sources complete.
* @param the value type
* @param sources the Iterable sequence of Iterables
* @param comparator the comparator to compare items and pick the one that returns negative will be picked
* @return the new Ix instance
* @since 1.0
*/
public static Ix orderedMerge(Iterable extends Iterable extends T>> sources, Comparator super T> comparator) {
return new IxOrderedMergeIterable(nullCheck(sources, "sources is null"), nullCheck(comparator, "comparator is null"));
}
/**
* Merges self-comparable items from an Iterable sequence of Iterable sequences, picking
* the smallest item from all those inner Iterables until all sources complete.
* @param the value type
* @param sources the Iterable sequence of Iterables of self-comparable items
* @return the new Ix instance
* @since 1.0
*/
public static > Ix orderedMergeArray(Iterable extends T>... sources) {
return orderedMergeArray(SelfComparator.INSTANCE, sources);
}
/**
* Merges items from an array of Iterable sequences, picking
* the smallest item (according to a custom comparator) from all those inner
* Iterables until all sources complete.
* @param the value type
* @param sources the Iterable sequence of Iterables
* @param comparator the comparator to compare items and pick the one that returns negative will be picked
* @return the new Ix instance
* @since 1.0
*/
public static Ix orderedMergeArray(Comparator super T> comparator, Iterable extends T>... sources) {
return new IxOrderedMergeArray(nullCheck(sources, "sources is null"), nullCheck(comparator, "comparator is null"));
}
/**
* Emits a range of incrementing integer values, starting from {@code start} and
* up to {@code count} times.
* @param start the starting value
* @param count the number of integers to emit, non-negative
* @return the new Ix instance
* @throws IllegalArgumentException if count is negative
* @since 1.0
*/
public static Ix range(int start, int count) {
if (count == 0) {
return empty();
}
if (count == 1) {
return just(start);
}
if (count < 0) {
throw new IllegalArgumentException("count >= 0 required but it was " + count);
}
return new IxRange(start, count);
}
/**
* Prevents the downstream from calling remove() and throws
* an UnsupportedOperationException instead.
* @return the new Ix instance
* @see #readOnly(boolean)
* @since 1.0
*/
public final Ix readOnly() {
return new IxReadOnly(this, false);
}
/**
* Prevents the downstream from calling remove() by optionally
* ignoring it or throwing an UnsupportedOperationException.
* @param silent if true, remove() calls are ignored; if false,
* remove() calls throw an UnsupportedOperationException
* @return the new Ix instance
* @since 1.0
*/
public final Ix readOnly(boolean silent) {
return new IxReadOnly(this, silent);
}
/**
* Repeatedly calls the given callable indefinitely and
* emits the returned value.
*
* The result's iterator() doesn't support remove().
* @param the value type
* @param callable the callable to call
* @return the new Ix instance
* @since 1.0
*/
public static Ix repeatCallable(Callable callable) {
return new IxRepeatCallable(nullCheck(callable, "callable is null"));
}
/**
* Repeats the given value indefinitely.
*
* The result's iterator() doesn't support remove().
* @param the value type
* @param value the value to emit whenever next() is called
* @return the new Ix instance
* @since 1.0
*/
public static Ix repeatValue(T value) {
return new IxRepeat(value);
}
/**
* Repeats the given value at most count times.
*
* A count of zero will yield an empty sequence, a count of one
* will yield a sequence with only one element and so forth.
*
* The result's iterator() doesn't support remove().
* @param the value type
* @param value the value to emit
* @param count the number of times to emit the value, non-negative
* @return the new Ix instance
* @throws IllegalArgumentException if count is negative
* @since 1.0
*/
public static Ix repeatValue(T value, long count) {
return new IxRepeatCount(value, nonNegative(count, "count"));
}
/**
* Repeats the given value until the given predicate returns true.
*
* A count of zero will yield an empty sequence, a count of one
* will yield a sequence with only one element and so forth.
*
* The result's iterator() doesn't support remove().
* @param the value type
* @param value the value to emit
* @param stopPredicate the predicate called before any emission; returning
* false keeps repeating the value, returning true terminates the sequence
* @return the new Ix instance
* @throws NullPointerException if stopPredicate is null
* @since 1.0
*/
public static Ix repeatValue(T value, IxBooleanSupplier stopPredicate) {
return repeatValue(value, Long.MAX_VALUE, stopPredicate);
}
/**
* Repeats the given value at most count times or until the given predicate returns true.
*
* A count of zero will yield an empty sequence, a count of one
* will yield a sequence with only one element and so forth.
*
* The result's iterator() doesn't support remove().
* @param the value type
* @param value the value to emit
* @param count the number of times to emit the value, non-negative
* @param stopPredicate the predicate called before any emission; returning
* false keeps repeating the value, returning true terminates the sequence
* @return the new Ix instance
* @throws IllegalArgumentException if count is negative
* @throws NullPointerException if stopPredicate is null
* @since 1.0
*/
public static Ix repeatValue(T value, long count, IxBooleanSupplier stopPredicate) {
return new IxRepeatPredicate(value, nonNegative(count, "count"), nullCheck(stopPredicate, "stopPredicate is null"));
}
/**
* Emits a sequence of substring of a string split by the given separator.
*
* The result's iterator() doesn't support remove().
* @param string the string to split, not null
* @param by the separator to split along, not null
* @return the new Ix instance
* @throws NullPointerException if string or by is null
* @since 1.0
*/
public static Ix split(String string, String by) {
return new IxSplit(nullCheck(string, "string is null"), nullCheck(by, "by is null"));
}
/**
* Combines the next element from each source Iterable via a zipper function.
*
* If one of the source Iterables is sorter the sequence terminates eagerly.
*
* The result's iterator() doesn't support remove().
*
* @param the common element type of the sources
* @param the result value type
* @param sources the array of Iterable sources, not null
* @param zipper the function that takes an array of values and returns a value
* to be emitted, one from each source, not null
* @return the new Ix instance
* @throws NullPointerException if sources or zipper is null
* @since 1.0
*/
public static Ix zip(Iterable extends T>[] sources, IxFunction super Object[], R> zipper) {
return new IxZipArray(nullCheck(sources, "sources is null"), nullCheck(zipper, "zipper is null"));
}
/**
* Combines the next element from each source Iterable, provided as an Iterable itself,
* via a zipper function.
*
* If one of the source Iterables is sorter the sequence terminates eagerly.
*
* The result's iterator() doesn't support remove().
*
* @param the common element type of the sources
* @param the result value type
* @param sources the Iterable of Iterable sources, not null
* @param zipper the function that takes an array of values and returns a value
* to be emitted, one from each source, not null
* @return the new Ix instance
* @throws NullPointerException if sources or zipper is null
* @since 1.0
*/
public static Ix zip(Iterable extends Iterable extends T>> sources, IxFunction super Object[], R> zipper) {
return new IxZipIterable(nullCheck(sources, "sources is null"), nullCheck(zipper, "zipper is null"));
}
/**
* Combines the next element from each source Iterable via a zipper function.
*
* If one of the source Iterables is sorter the sequence terminates eagerly.
*
* The result's iterator() doesn't support remove().
*
* @param the first source's element type
* @param the second source's element type
* @param the result value type
* @param source1 the first source Iterable
* @param source2 the second source Iterable
* @param zipper the function that takes one from each source, not null
* @return the new Ix instance
* @throws NullPointerException if any of the sources or zipper is null
* @since 1.0
*/
public static Ix zip(
Iterable source1, Iterable source2,
IxFunction2 super T1, ? super T2, ? extends R> zipper) {
return new IxZip2(nullCheck(source1, "source1 is null"),
nullCheck(source2, "source2 is null"), nullCheck(zipper, "zipper is null"));
}
/**
* Combines the next element from each source Iterable via a zipper function.
*
* If one of the source Iterables is sorter the sequence terminates eagerly.
*
* The result's iterator() doesn't support remove().
*
* @param the first source's element type
* @param the second source's element type
* @param the third source's element type
* @param the result value type
* @param source1 the first source Iterable
* @param source2 the second source Iterable
* @param source3 the third source Iterable
* @param zipper the function that takes one from each source, not null
* @return the new Ix instance
* @throws NullPointerException if any of the sources or zipper is null
* @since 1.0
*/
public static Ix zip(
Iterable source1, Iterable source2,
Iterable source3,
IxFunction3 super T1, ? super T2, ? super T3, ? extends R> zipper) {
return new IxZip3(nullCheck(source1, "source1 is null"), nullCheck(source2, "source2 is null"),
nullCheck(source3, "source3 is null"), nullCheck(zipper, "zipper is null"));
}
/**
* Combines the next element from each source Iterable via a zipper function.
*
* If one of the source Iterables is sorter the sequence terminates eagerly.
*
* The result's iterator() doesn't support remove().
*
* @param the first source's element type
* @param the second source's element type
* @param the third source's element type
* @param the fourth source's element type
* @param the result value type
* @param source1 the first source Iterable
* @param source2 the second source Iterable
* @param source3 the third source Iterable
* @param source4 the fourth source Iterable
* @param zipper the function that takes one from each source, not null
* @return the new Ix instance
* @throws NullPointerException if any of the sources or zipper is null
* @since 1.0
*/
public static Ix zip(
Iterable source1, Iterable source2,
Iterable source3, Iterable source4,
IxFunction4 super T1, ? super T2, ? super T3, ? super T4, ? extends R> zipper) {
return new IxZip4(nullCheck(source1, "source1 is null"),
nullCheck(source2, "source2 is null"), nullCheck(source3, "source3 is null"),
nullCheck(source4, "source4 is null"), nullCheck(zipper, "zipper is null"));
}
//---------------------------------------------------------------------------------------
// Instance operators
//---------------------------------------------------------------------------------------
/**
* Emits true if all elements of this sequence match a given predicate (including empty).
*
* The result's iterator() doesn't support remove().
* @param predicate the predicate receiving each element
* @return the new Ix instance
* @throws NullPointerException if predicate is null
* @since 1.0
*/
public final Ix all(IxPredicate super T> predicate) {
return new IxAll(this, nullCheck(predicate, "predicate is null"));
}
/**
* Emits true if any element of this sequence matches the given predicate,
* false otherwise (or for empty sequences).
*
* The result's iterator() doesn't support remove().
* @param predicate the predicate receiving each element
* @return the new Ix instance
* @throws NullPointerException if predicate is null
* @since 1.0
*/
public final Ix any(IxPredicate super T> predicate) {
return new IxAny(this, nullCheck(predicate, "predicate is null"));
}
/**
* Calls the given transformers with this and returns its value allowing
* fluent conversions to non-Ix types.
* @param the result type
* @param transformer the function receiving this Ix instance and returns a value
* @return the value returned by the transformer function
* @throws NullPointerException if transformer is null
* @since 1.0
*/
public final R as(IxFunction super Ix, R> transformer) {
return transformer.apply(this);
}
/**
* Calculates the float-based average of this sequence of numbers.
* The returned sequence is empty if this sequence is empty.
*
This operator force-casts this sequence which may lead
* to ClassCastException if any of this sequence's elements is not
* a subclass of Number.
*
* The result's iterator() doesn't support remove().
* @return the new Ix instance
* @since 1.0
*/
@SuppressWarnings("unchecked")
public final Ix averageFloat() {
return new IxAverageFloat((Iterable)this);
}
/**
* Calculates the double-based average of this sequence of numbers.
* The returned sequence is empty if this sequence is empty.
*
This operator force-casts this sequence which may lead
* to ClassCastException if any of this sequence's elements is not
* a subclass of Number.
*
* The result's iterator() doesn't support remove().
* @return the new Ix instance
* @since 1.0
*/
@SuppressWarnings("unchecked")
public final Ix averageDouble() {
return new IxAverageDouble((Iterable)this);
}
/**
* Buffers the subsequent {@code size} elements into a sequence of
* non-overlapping Lists.
*
* The result's iterator() doesn't support remove().
* @param size the number of elements to group together, positive
* @return the new Ix instance
* @throws IllegalArgumentException if size is non-positive
* @since 1.0
*/
public final Ix> buffer(int size) {
return new IxBuffer(this, positive(size, "size"));
}
/**
* Buffers the subsequent {@code size} elements into a sequence of
* potentially overlapping Lists.
*
* The result's iterator() doesn't support remove().
* @param size the number of elements to group together, positive
* @param skip specifies how often to start a new list
* @return the new Ix instance
* @throws IllegalArgumentException if size or skip is non-positive
* @since 1.0
*/
public final Ix> buffer(int size, int skip) {
if (size == skip) {
return buffer(size);
}
if (size < skip) {
return new IxBufferSkip(this, positive(size, "size"), positive(skip, "skip"));
}
return new IxBufferOverlap(this, positive(size, "size"), positive(skip, "skip"));
}
/**
* Buffer until an item is encountered for which the predicate returns true,
* triggering a new buffer.
* Neither the previous nor the next buffer will contain the item that caused the
* split
* @param predicate the predicate called with each item and should return false
* to trigger a new buffer
* @return the new Ix instance
* @see #bufferUntil(IxPredicate)
* @see #bufferWhile(IxPredicate)
* @since 1.0
*/
public final Ix> bufferSplit(IxPredicate super T> predicate) {
return new IxBufferSplit(this, nullCheck(predicate, "predicate is null"));
}
/**
* Buffer until an item is encountered after which the predicate returns true
* to start a new buffer.
* The item will be part of the previous buffer.
* @param predicate the predicate called with each item after the item
* has been added to the current buffer and should return true to start a new buffer
* @return the new Ix instance
* @see #bufferSplit(IxPredicate)
* @see #bufferWhile(IxPredicate)
* @since 1.0
*/
public final Ix> bufferUntil(IxPredicate super T> predicate) {
return new IxBufferUntil(this, nullCheck(predicate, "predicate is null"));
}
/**
* Buffer while an item is encountered before which the predicate returns false
* to start a new buffer.
* The item will be part of the next buffer
* @param predicate the predicate called with each item after the item
* has been added to the current buffer and should return true to start a new buffer
* @return the new Ix instance
* @see #bufferSplit(IxPredicate)
* @see #bufferUntil(IxPredicate)
* @since 1.0
*/
public final Ix> bufferWhile(IxPredicate super T> predicate) {
return new IxBufferWhile(this, nullCheck(predicate, "predicate is null"));
}
/**
* Cast the elements to the specified class.
*
* Note that this is a forced cast on this Ix instance and if
* not compatible, a ClassCastException might be thrown downstream.
* @param the target type
* @param clazz the type token to capture the target type
* @return the new Ix instance
* @since 1.0
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public final Ix cast(Class clazz) {
return (Ix)this;
}
/**
* Collect the elements into a collection via collector action and emit that collection
* as a single item.
*
* The result's iterator() doesn't support remove().
* @param the collection type
* @param initialFactory the function returning a collection for each iterator() call
* @param collector the action called with the collection and the current item
* @return the new Ix instance
* @throws NullPointerException if initialFactory or collector is null
* @since 1.0
*/
public final Ix collect(IxSupplier initialFactory, IxConsumer2 collector) {
return new IxCollect(this, nullCheck(initialFactory, "initialFactory is null"), nullCheck(collector, "collector"));
}
/**
* Collects the elements of this sequence into an Object array.
*
* The result's iterator() doesn't support remove().
* @return the new Ix instance
* @since 1.0
*/
public final Ix