com.tangosol.util.stream.RemoteStream Maven / Gradle / Ivy
Show all versions of coherence Show documentation
/*
* Copyright (c) 2000, 2021, Oracle and/or its affiliates.
*
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
package com.tangosol.util.stream;
import com.tangosol.internal.util.invoke.Lambdas;
import com.tangosol.internal.util.stream.StreamSupport;
import com.tangosol.util.Filters;
import com.tangosol.util.InvocableMap;
import com.tangosol.util.ValueExtractor;
import com.tangosol.util.comparator.ExtractorComparator;
import com.tangosol.util.comparator.InverseComparator;
import com.tangosol.util.function.Remote;
import java.util.Comparator;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.stream.Collector;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;
/**
* This interface is an extension of {@code java.util.stream.Stream} that captures
* lambdas used as method arguments as serializable lambdas.
*
* @param the type of the stream elements
*
* @author as 2014.08.11
* @since 12.2.1
*
* @see RemoteIntStream
* @see RemoteLongStream
* @see RemoteDoubleStream
* @see com.tangosol.util.stream
*/
public interface RemoteStream
extends Stream, BaseRemoteStream>
{
/**
* Create a {@link RemoteStream} of specified map's entries.
*
* @param map the map to create a remote stream for
* @param the type of map keys
* @param the type of map values
*
* @return a {@link RemoteStream} of specified map's entries
*/
public static RemoteStream> entrySet(InvocableMap map)
{
return StreamSupport
.entryStream(map, true, null, Filters.always());
}
/**
* Create a {@link RemoteStream} of specified map's keys.
*
* @param map the map to create a remote stream for
* @param the type of map keys
* @param the type of map values
*
* @return a {@link RemoteStream} of specified map's keys
*/
public static RemoteStream keySet(InvocableMap map)
{
return StreamSupport
.entryStream(map, true, null, Filters.always())
.map(InvocableMap.Entry::getKey);
}
/**
* Create a {@link RemoteStream} of specified map's values.
*
* @param map the map to create a remote stream for
* @param the type of map keys
* @param the type of map values
*
* @return a {@link RemoteStream} of specified map's values
*/
public static RemoteStream values(InvocableMap map)
{
return StreamSupport
.entryStream(map, true, null, Filters.always())
.map(InvocableMap.Entry::getValue);
}
/**
* Returns an equivalent stream that is sequential. May return itself,
* either because the stream was already sequential, or because the
* underlying stream state was modified to be sequential.
*
* This is an intermediate operation.
*
* @return a sequential stream
*/
RemoteStream sequential();
/**
* Returns an equivalent stream that is parallel. May return itself, either
* because the stream was already parallel, or because the underlying stream
* state was modified to be parallel.
*
* This is an intermediate operation.
*
* @return a parallel stream
*/
RemoteStream parallel();
/**
* Returns an equivalent stream that is unordered.
* May return itself, either because the stream was already unordered, or
* because the underlying stream state670G was modified to be unordered.
*
* This is an intermediate operation.
*
* @return an unordered stream
*/
RemoteStream unordered();
/**
* Returns a stream consisting of the elements of this stream that match the
* given predicate.
*
* This is an intermediate operation.
*
* @param predicate a non-interfering, stateless predicate to apply to each
* element to determine if it should be included
*
* @return the new stream
*/
RemoteStream filter(Predicate super T> predicate);
/**
* Returns a stream consisting of the elements of this stream that match the
* given predicate.
*
* This is an intermediate operation.
*
* @param predicate a non-interfering, stateless predicate to apply to each
* element to determine if it should be included
*
* @return the new stream
*/
default RemoteStream filter(Remote.Predicate super T> predicate)
{
return filter((Predicate super T>) predicate);
}
/**
* Returns a stream consisting of the results of applying the given function
* to the elements of this stream.
*
* This is an intermediate operation.
*
* @param mapper a non-interfering, stateless
* function to apply to each element
*
* @return the new stream
*/
RemoteStream map(Function super T, ? extends R> mapper);
/**
* Returns a stream consisting of the results of applying the given function
* to the elements of this stream.
*
* This is an intermediate operation.
*
* @param the type of resulting stream elements
* @param mapper a non-interfering, stateless
* function to apply to each element
*
* @return the new stream
*/
default RemoteStream map(Remote.Function super T, ? extends R> mapper)
{
return map((Function super T, ? extends R>) mapper);
}
/**
* Returns a stream consisting of the results of applying the given extractor
* to the elements of this stream.
*
* This is an intermediate operation.
*
* @param the type of resulting stream elements
* @param mapper a non-interfering, stateless
* function to apply to each element
*
* @return the new stream
*/
default RemoteStream map(ValueExtractor super T, ? extends R> mapper)
{
return map((Function super T, ? extends R>) Lambdas.ensureRemotable(mapper));
}
/**
* Returns an {@code IntStream} consisting of the results of applying the
* given function to the elements of this stream.
*
* This is an intermediate operation.
*
* @param mapper a non-interfering, stateless
* function to apply to each element
*
* @return the new stream
*/
RemoteIntStream mapToInt(ToIntFunction super T> mapper);
/**
* Returns an {@code IntStream} consisting of the results of applying the
* given function to the elements of this stream.
*
* This is an intermediate operation.
*
* @param mapper a non-interfering, stateless
* function to apply to each element
*
* @return the new stream
*/
default RemoteIntStream mapToInt(Remote.ToIntFunction super T> mapper)
{
return mapToInt((ToIntFunction super T>) mapper);
}
/**
* Returns an {@code IntStream} consisting of the results of applying the
* given extractor to the elements of this stream.
*
* This is an intermediate operation.
*
* @param mapper a non-interfering, stateless
* function to apply to each element
*
* @return the new stream
*/
default RemoteIntStream mapToInt(ValueExtractor super T, ? extends Number> mapper)
{
return mapToInt((ToIntFunction super T>) Lambdas.ensureRemotable(mapper));
}
/**
* Returns a {@code LongStream} consisting of the results of applying the
* given function to the elements of this stream.
*
* This is an intermediate operation.
*
* @param mapper a non-interfering, stateless
* function to apply to each element
*
* @return the new stream
*/
RemoteLongStream mapToLong(ToLongFunction super T> mapper);
/**
* Returns a {@code LongStream} consisting of the results of applying the
* given function to the elements of this stream.
*
* This is an intermediate operation.
*
* @param mapper a non-interfering, stateless
* function to apply to each element
*
* @return the new stream
*/
default RemoteLongStream mapToLong(Remote.ToLongFunction super T> mapper)
{
return mapToLong((ToLongFunction super T>) mapper);
}
/**
* Returns an {@code LongStream} consisting of the results of applying the
* given extractor to the elements of this stream.
*
* This is an intermediate operation.
*
* @param mapper a non-interfering, stateless
* function to apply to each element
*
* @return the new stream
*/
default RemoteLongStream mapToLong(ValueExtractor super T, ? extends Number> mapper)
{
return mapToLong((ToLongFunction super T>) Lambdas.ensureRemotable(mapper));
}
/**
* Returns a {@code DoubleStream} consisting of the results of applying the
* given function to the elements of this stream.
*
* This is an intermediate operation.
*
* @param mapper a non-interfering, stateless
* function to apply to each element
*
* @return the new stream
*/
RemoteDoubleStream mapToDouble(ToDoubleFunction super T> mapper);
/**
* Returns a {@code DoubleStream} consisting of the results of applying the
* given function to the elements of this stream.
*
* This is an intermediate operation.
*
* @param mapper a non-interfering, stateless
* function to apply to each element
*
* @return the new stream
*/
default RemoteDoubleStream mapToDouble(Remote.ToDoubleFunction super T> mapper)
{
return mapToDouble((ToDoubleFunction super T>) mapper);
}
/**
* Returns an {@code DoubleStream} consisting of the results of applying the
* given extractor to the elements of this stream.
*
* This is an intermediate operation.
*
* @param mapper a non-interfering, stateless
* function to apply to each element
*
* @return the new stream
*/
default RemoteDoubleStream mapToDouble(ValueExtractor super T, ? extends Number> mapper)
{
return mapToDouble((ToDoubleFunction super T>) Lambdas.ensureRemotable(mapper));
}
/**
* Returns a stream consisting of the results of replacing each element of
* this stream with the contents of a mapped stream produced by applying
* the provided mapping function to each element. Each mapped stream is
* {@link BaseRemoteStream#close() closed} after its contents have been placed
* into this stream. (If a mapped stream is {@code null} an empty stream
* is used, instead.)
*
* This is an intermediate operation.
*
* @param The element type of the new stream
* @param mapper a non-interfering, stateless
* function to apply to each element which produces a stream
* of new values
*
* @return the new stream
*/
RemoteStream flatMap(Function super T, ? extends Stream extends R>> mapper);
/**
* Returns a stream consisting of the results of replacing each element of
* this stream with the contents of a mapped stream produced by applying
* the provided mapping function to each element. Each mapped stream is
* {@link BaseRemoteStream#close() closed} after its contents have been placed
* into this stream. (If a mapped stream is {@code null} an empty stream
* is used, instead.)
*
* This is an intermediate operation.
*
* @param The element type of the new stream
* @param mapper a non-interfering, stateless
* function to apply to each element which produces a stream
* of new values
*
* @return the new stream
*/
default RemoteStream flatMap(Remote.Function super T, ? extends Stream extends R>> mapper)
{
Function super T, ? extends Stream extends R>> safeMapper =
Remote.function(t -> t == null ? null : mapper.apply(t));
return flatMap(safeMapper);
}
/**
* Returns an {@code IntStream} consisting of the results of replacing each
* element of this stream with the contents of a mapped stream produced by
* applying the provided mapping function to each element. Each mapped
* stream is {@link BaseRemoteStream#close() closed} after its contents have been
* placed into this stream. (If a mapped stream is {@code null} an empty
* stream is used, instead.)
*
* This is an intermediate operation.
*
* @param mapper a non-interfering, stateless
* function to apply to each element which produces a stream
* of new values
*
* @return the new stream
*
* @see #flatMap(Function)
*/
RemoteIntStream flatMapToInt(Function super T, ? extends IntStream> mapper);
/**
* Returns an {@code IntStream} consisting of the results of replacing each
* element of this stream with the contents of a mapped stream produced by
* applying the provided mapping function to each element. Each mapped
* stream is {@link BaseRemoteStream#close() closed} after its contents have been
* placed into this stream. (If a mapped stream is {@code null} an empty
* stream is used, instead.)
*
* This is an intermediate operation.
*
* @param mapper a non-interfering, stateless
* function to apply to each element which produces a stream
* of new values
*
* @return the new stream
*
* @see #flatMap(Function)
*/
default RemoteIntStream flatMapToInt(Remote.Function super T, ? extends IntStream> mapper)
{
Function super T, ? extends IntStream> safeMapper =
Remote.function(t -> t == null ? null : mapper.apply(t));
return flatMapToInt(safeMapper);
}
/**
* Returns an {@code LongStream} consisting of the results of replacing each
* element of this stream with the contents of a mapped stream produced by
* applying the provided mapping function to each element. Each mapped
* stream is {@link BaseRemoteStream#close() closed} after its contents have been
* placed into this stream. (If a mapped stream is {@code null} an empty
* stream is used, instead.)
*
* This is an intermediate operation.
*
* @param mapper a non-interfering, stateless
* function to apply to each element which produces a stream
* of new values
*
* @return the new stream
*
* @see #flatMap(Function)
*/
RemoteLongStream flatMapToLong(Function super T, ? extends LongStream> mapper);
/**
* Returns an {@code LongStream} consisting of the results of replacing each
* element of this stream with the contents of a mapped stream produced by
* applying the provided mapping function to each element. Each mapped
* stream is {@link BaseRemoteStream#close() closed} after its contents have been
* placed into this stream. (If a mapped stream is {@code null} an empty
* stream is used, instead.)
*
* This is an intermediate operation.
*
* @param mapper a non-interfering, stateless
* function to apply to each element which produces a stream
* of new values
*
* @return the new stream
*
* @see #flatMap(Function)
*/
default RemoteLongStream flatMapToLong(Remote.Function super T, ? extends LongStream> mapper)
{
Function super T, ? extends LongStream> safeMapper =
Remote.function(t -> t == null ? null : mapper.apply(t));
return flatMapToLong(safeMapper);
}
/**
* Returns an {@code DoubleStream} consisting of the results of replacing
* each element of this stream with the contents of a mapped stream produced
* by applying the provided mapping function to each element. Each mapped
* stream is {@link BaseRemoteStream#close() closed} after its contents have been
* placed into this stream. (If a mapped stream is {@code null} an empty
* stream is used, instead.)
*
* This is an intermediate operation.
*
* @param mapper a non-interfering, stateless
* function to apply to each element which produces a stream
* of new values
*
* @return the new stream
*
* @see #flatMap(Function)
*/
RemoteDoubleStream flatMapToDouble(Function super T, ? extends DoubleStream> mapper);
/**
* Returns an {@code DoubleStream} consisting of the results of replacing
* each element of this stream with the contents of a mapped stream produced
* by applying the provided mapping function to each element. Each mapped
* stream is {@link BaseRemoteStream#close() closed} after its contents have been
* placed into this stream. (If a mapped stream is {@code null} an empty
* stream is used, instead.)
*
* This is an intermediate operation.
*
* @param mapper a non-interfering, stateless
* function to apply to each element which produces a stream
* of new values
*
* @return the new stream
*
* @see #flatMap(Function)
*/
default RemoteDoubleStream flatMapToDouble(Remote.Function super T, ? extends DoubleStream> mapper)
{
Function super T, ? extends DoubleStream> safeMapper =
Remote.function(t -> t == null ? null : mapper.apply(t));
return flatMapToDouble(safeMapper);
}
/**
* Returns a stream consisting of the elements of this stream, additionally
* performing the provided action on each element as elements are consumed
* from the resulting stream.
*
* This is an intermediate operation.
*
* For parallel stream pipelines, the action may be called at whatever
* time and in whatever thread the element is made available by the upstream
* operation. If the action modifies shared state, it is responsible for
* providing the required synchronization.
*
* @param action a non-interfering action to perform on the elements as they
* are consumed from the stream
*
* @return the new stream
*/
RemoteStream peek(Consumer super T> action);
/**
* Returns a stream consisting of the elements of this stream, additionally
* performing the provided action on each element as elements are consumed
* from the resulting stream.
*
* This is an intermediate operation.
*
* For parallel stream pipelines, the action may be called at whatever
* time and in whatever thread the element is made available by the upstream
* operation. If the action modifies shared state, it is responsible for
* providing the required synchronization.
*
* @param action a non-interfering action to perform on the elements as they
* are consumed from the stream
*
* @return the new stream
*/
default RemoteStream peek(Remote.Consumer super T> action)
{
return peek((Consumer super T>) action);
}
/**
* Returns a stream consisting of the elements of this stream, truncated to
* be no longer than {@code maxSize} in length.
*
* This is a short-circuiting stateful intermediate operation.
*
* @param maxSize the number of elements the stream should be limited to
*
* @return the new stream
*
* @throws IllegalArgumentException if {@code maxSize} is negative
*/
Stream limit(long maxSize);
/**
* Returns a stream consisting of the remaining elements of this stream
* after discarding the first {@code n} elements of the stream.
* If this stream contains fewer than {@code n} elements then an
* empty stream will be returned.
*
* This is a stateful intermediate operation.
*
* @param n the number of leading elements to skip
*
* @return the new stream
*
* @throws IllegalArgumentException if {@code n} is negative
*/
Stream skip(long n);
/**
* Returns a stream consisting of the distinct elements (according to
* {@link Object#equals(Object)}) of this stream.
*
* For ordered streams, the selection of distinct elements is stable
* (for duplicated elements, the element appearing first in the encounter
* order is preserved.) For unordered streams, no stability guarantees
* are made.
*
* This is a stateful intermediate operation.
*
* @return the new stream
*/
Stream distinct();
/**
* Returns a stream consisting of the elements of this stream, sorted
* according to natural order. If the elements of this stream are not
* {@code Comparable}, a {@code java.lang.ClassCastException} may be thrown
* when the terminal operation is executed.
*
* For ordered streams, the sort is stable. For unordered streams, no
* stability guarantees are made.
*
* This is a stateful intermediate operation.
*
* @return the new stream
*/
RemoteStream sorted();
/**
* Returns a stream consisting of the elements of this stream, sorted
* according to the provided {@code Comparator}.
*
* For ordered streams, the sort is stable. For unordered streams, no
* stability guarantees are made.
*
* This is a stateful intermediate operation.
*
* @param comparator a non-interfering, stateless
* {@code Comparator} to be used to compare stream elements
*
* @return the new stream
*/
RemoteStream sorted(Comparator super T> comparator);
/**
* Returns a stream consisting of the elements of this stream, sorted
* according to the provided {@code Comparator}.
*
* For ordered streams, the sort is stable. For unordered streams, no
* stability guarantees are made.
*
*
This is a stateful
* intermediate operation.
*
* @param comparator a non-interfering, stateless
* {@code Comparator} to be used to compare stream elements
*
* @return the new stream
*/
default RemoteStream sorted(Remote.Comparator super T> comparator)
{
return sorted(comparator, false);
}
/**
* Returns a stream consisting of the elements of this stream, sorted
* according to the provided {@code Comparator}.
*
* For ordered streams, the sort is stable. For unordered streams, no
* stability guarantees are made.
*
*
This is a stateful
* intermediate operation.
*
* @param comparator a non-interfering, stateless
* {@code Comparator} to be used to compare stream elements
* @param fInverse a flag specifying whether to invert the sort order
*
* @return the new stream
*/
default RemoteStream sorted(Remote.Comparator super T> comparator, boolean fInverse)
{
Comparator super T> c = fInverse ? new InverseComparator<>(comparator) : comparator;
return sorted(c);
}
/**
* Returns a stream consisting of the elements of this stream, sorted
* according to attribute extracted by the provided {@code ValueExtractor}.
*
* For ordered streams, the sort is stable. For unordered streams, no
* stability guarantees are made.
*
*
This is a stateful
* intermediate operation.
*
* @param a super type of the value to extract from
* @param extractor a non-interfering, stateless
* {@code ValueExtractor} to be used to extract the attribute
* that should be used to compare stream elements
*
* @return the new stream
*/
default RemoteStream sorted(ValueExtractor super U, ? extends Comparable> extractor)
{
return sorted(extractor, false);
}
/**
* Returns a stream consisting of the elements of this stream, sorted
* according to attribute extracted by the provided {@code ValueExtractor}.
*
* For ordered streams, the sort is stable. For unordered streams, no
* stability guarantees are made.
*
*
This is a stateful
* intermediate operation.
*
* @param the super type of value to extract from
* @param extractor a non-interfering, stateless
* {@code ValueExtractor} to be used to extract the attribute
* that should be used to compare stream elements
* @param fInverse a flag specifying whether to invert natural sort order
*
* @return the new stream
*/
default RemoteStream sorted(ValueExtractor super U, ? extends Comparable> extractor, boolean fInverse)
{
Comparator comparator = new ExtractorComparator(extractor);
if (fInverse)
{
comparator = new InverseComparator<>(comparator);
}
return sorted(comparator);
}
/**
* Performs an action for each element of this stream.
*
* This is a terminal operation.
*
* @param action a non-interfering action to perform on the elements
*/
void forEach(Consumer super T> action);
/**
* Performs an action for each element of this stream, in the encounter
* order of the stream if the stream has a defined encounter order.
*
* This is a terminal operation.
*
* This operation processes the elements one at a time, in encounter
* order if one exists. Performing the action for one element
* happens-before performing the action for subsequent elements,
* but for any given element, the action may be performed in whatever thread
* the library chooses.
*
* @param action a non-interfering action to perform on the elements
*
* @see #forEach(Consumer)
*/
void forEachOrdered(Consumer super T> action);
/**
* Returns an array containing the elements of this stream.
*
* This is a terminal operation.
*
* @return an array containing the elements of this stream
*/
Object[] toArray();
/**
* Returns an array containing the elements of this stream, using the
* provided {@code generator} function to allocate the returned array, as
* well as any additional arrays that might be required for a partitioned
* execution or for resizing.
*
* This is a terminal operation.
*
* @param generator a function which produces a new array of the desired
* type and the provided length
*
* @return an array containing the elements in this stream
*
* @throws ArrayStoreException if the runtime type of the array returned
* from the array generator is not a supertype
* of the runtime type of every element in this
* stream
*/
A[] toArray(IntFunction generator);
/**
* Performs a reduction on the elements of this stream, using the provided
* identity value and an associative accumulation function, and returns the
* reduced value. This is equivalent to:
* {@code
* T result = identity;
* for (T element : this stream)
* result = accumulator.apply(result, element)
* return result;
* }
*
* but is not constrained to execute sequentially.
*
* The {@code identity} value must be an identity for the accumulator
* function. This means that for all {@code t}, {@code
* accumulator.apply(identity, t)} is equal to {@code t}. The {@code
* accumulator} function must be an associative function.
*
* This is a terminal operation.
*
* @param identity the identity value for the accumulating function
* @param accumulator an associative, non-interfering, stateless function
* for combining two values
*
* @return the result of the reduction
*/
T reduce(T identity, BinaryOperator accumulator);
/**
* Performs a reduction on the elements of this stream, using the provided
* identity value and an associative accumulation function, and returns the
* reduced value. This is equivalent to:
* {@code
* T result = identity;
* for (T element : this stream)
* result = accumulator.apply(result, element)
* return result;
* }
*
* but is not constrained to execute sequentially.
*
* The {@code identity} value must be an identity for the accumulator
* function. This means that for all {@code t}, {@code
* accumulator.apply(identity, t)} is equal to {@code t}. The {@code
* accumulator} function must be an associative function.
*
* This is a terminal operation.
*
* @param identity the identity value for the accumulating function
* @param accumulator an associative, non-interfering, stateless function
* for combining two values
*
* @return the result of the reduction
*/
default T reduce(T identity, Remote.BinaryOperator accumulator)
{
return reduce(identity, (BinaryOperator) accumulator);
}
/**
* Performs a reduction on the elements of this stream, using an associative
* accumulation function, and returns an {@code Optional} describing the
* reduced value, if any. This is equivalent to:
* {@code
* boolean foundAny = false;
* T result = null;
* for (T element : this stream) {
* if (!foundAny) {
* foundAny = true;
* result = element;
* }
* else
* result = accumulator.apply(result, element);
* }
* return foundAny ? Optional.of(result) : Optional.empty();
* }
*
* but is not constrained to execute sequentially.
*
* The {@code accumulator} function must be an associative function.
*
* This is a terminal operation.
*
* @param accumulator an associative, non-interfering, stateless function
* for combining two values
*
* @return an {@link Optional} describing the result of the reduction
*
* @throws NullPointerException if the result of the reduction is null
* @see #reduce(Object, Remote.BinaryOperator)
* @see #min(Comparator)
* @see #max(Comparator)
*/
Optional reduce(BinaryOperator accumulator);
/**
* Performs a reduction on the elements of this stream, using an associative
* accumulation function, and returns an {@code Optional} describing the
* reduced value, if any. This is equivalent to:
* {@code
* boolean foundAny = false;
* T result = null;
* for (T element : this stream) {
* if (!foundAny) {
* foundAny = true;
* result = element;
* }
* else
* result = accumulator.apply(result, element);
* }
* return foundAny ? Optional.of(result) : Optional.empty();
* }
*
* but is not constrained to execute sequentially.
*
* The {@code accumulator} function must be an associative function.
*
* This is a terminal operation.
*
* @param accumulator an associative, non-interfering, stateless function
* for combining two values
*
* @return an {@link Optional} describing the result of the reduction
*
* @throws NullPointerException if the result of the reduction is null
* @see #reduce(Object, Remote.BinaryOperator)
* @see #min(Comparator)
* @see #max(Comparator)
*/
default Optional reduce(Remote.BinaryOperator accumulator)
{
return reduce((BinaryOperator) accumulator);
}
/**
* Performs a reduction on the elements of this stream, using the provided
* identity, accumulation and combining functions. This is equivalent to:
* {@code
* U result = identity;
* for (T element : this stream)
* result = accumulator.apply(result, element)
* return result;
* }
*
* but is not constrained to execute sequentially.
*
* The {@code identity} value must be an identity for the combiner function.
* This means that for all {@code u}, {@code combiner(identity, u)} is
* equal to {@code u}. Additionally, the {@code combiner} function must be
* compatible with the {@code accumulator} function; for all {@code u} and
* {@code t}, the following must hold:
*
{@code
* combiner.apply(u, accumulator.apply(identity, t)) ==
* accumulator.apply(u, t)
* }
*
* This is a terminal operation.
*
* @param identity the identity value for the combiner function
* @param accumulator an associative, non-interfering, stateless function
* for incorporating an additional element into a result
* @param combiner an associative, non-interfering, stateless function
* for combining two values, which must be compatible
* with the accumulator function
*
* @return the result of the reduction
*
* @see #reduce(Remote.BinaryOperator)
* @see #reduce(Object, Remote.BinaryOperator)
*/
U reduce(U identity, BiFunction accumulator, BinaryOperator combiner);
/**
* Performs a reduction on the elements of this stream, using the provided
* identity, accumulation and combining functions. This is equivalent to:
* {@code
* U result = identity;
* for (T element : this stream)
* result = accumulator.apply(result, element)
* return result;
* }
*
* but is not constrained to execute sequentially.
*
* The {@code identity} value must be an identity for the combiner function.
* This means that for all {@code u}, {@code combiner(identity, u)} is
* equal to {@code u}. Additionally, the {@code combiner} function must be
* compatible with the {@code accumulator} function; for all {@code u} and
* {@code t}, the following must hold:
*
{@code
* combiner.apply(u, accumulator.apply(identity, t)) ==
* accumulator.apply(u, t)
* }
*
* This is a terminal operation.
*
* @param the type of stream elements
* @param identity the identity value for the combiner function
* @param accumulator an associative, non-interfering, stateless function
* for incorporating an additional element into a result
* @param combiner an associative, non-interfering, stateless function
* for combining two values, which must be compatible
* with the accumulator function
*
* @return the result of the reduction
*
* @see #reduce(Remote.BinaryOperator)
* @see #reduce(Object, Remote.BinaryOperator)
*/
default U reduce(U identity, Remote.BiFunction accumulator, Remote.BinaryOperator combiner)
{
return reduce(identity, (BiFunction) accumulator, (BinaryOperator) combiner);
}
/**
* Performs a mutable reduction operation on the elements of this stream. A
* mutable reduction is one in which the reduced value is a mutable result
* container, such as an {@code ArrayList}, and elements are incorporated by
* updating the state of the result rather than by replacing the result.
* This produces a result equivalent to:
* {@code
* R result = supplier.get();
* for (T element : this stream)
* accumulator.accept(result, element);
* return result;
* }
*
* Like {@link #reduce(Object, Remote.BinaryOperator)}, {@code collect}
* operations can be parallelized without requiring additional
* synchronization.
*
* This is a terminal operation.
*
* @param supplier a function that creates a new result container. For a
* parallel execution, this function may be called
* multiple times and must return a fresh value each
* time.
* @param accumulator an associative, non-interfering, stateless function
* for incorporating an additional element into a result
* @param combiner an associative, non-interfering, stateless function
* for combining two values, which must be compatible
* with the accumulator function
*
* @return the result of the reduction
*/
R collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner);
/**
* Performs a mutable reduction operation on the elements of this stream. A
* mutable reduction is one in which the reduced value is a mutable result
* container, such as an {@code ArrayList}, and elements are incorporated by
* updating the state of the result rather than by replacing the result.
* This produces a result equivalent to:
* {@code
* R result = supplier.get();
* for (T element : this stream)
* accumulator.accept(result, element);
* return result;
* }
*
* Like {@link #reduce(Object, Remote.BinaryOperator)}, {@code collect}
* operations can be parallelized without requiring additional
* synchronization.
*
* This is a terminal operation.
*
* @param the result type
* @param supplier a function that creates a new result container. For a
* parallel execution, this function may be called
* multiple times and must return a fresh value each
* time.
* @param accumulator an associative, non-interfering, stateless function
* for incorporating an additional element into a result
* @param combiner an associative, non-interfering, stateless function
* for combining two values, which must be compatible
* with the accumulator function
*
* @return the result of the reduction
*/
default R collect(Remote.Supplier supplier, Remote.BiConsumer accumulator, Remote.BiConsumer combiner)
{
return collect((Supplier) supplier, (BiConsumer) accumulator, (BiConsumer) combiner);
}
/**
* Performs a mutable reduction operation on the elements of this stream
* using a {@code Collector}. A {@code Collector} encapsulates the
* functions used as arguments to {@link #collect(Remote.Supplier,
* Remote.BiConsumer, Remote.BiConsumer)}, allowing for reuse of collection
* strategies and composition of collect operations such as multiple-level
* grouping or partitioning.
*
* If the stream is parallel, and the {@code Collector} is {@link
* RemoteCollector.Characteristics#CONCURRENT concurrent}, and either the stream
* is unordered or the collector is {@link RemoteCollector.Characteristics#UNORDERED
* unordered}, then a concurrent reduction will be performed (see {@link
* RemoteCollector} for details on concurrent reduction.)
*
* This is a terminal operation.
*
* @param collector the {@code Collector} describing the reduction
*
* @return the result of the reduction
*
* @see #collect(Remote.Supplier, Remote.BiConsumer, Remote.BiConsumer)
*/
default R collect(Collector super T, A, R> collector)
{
if (collector instanceof RemoteCollector)
{
return collect((RemoteCollector super T, A, R>) collector);
}
throw new UnsupportedOperationException("java.util.stream.Collector is not supported. "
+ "Please use com.tangosol.util.stream.RemoteCollector instead.");
}
/**
* Performs a mutable reduction operation on the elements of this stream
* using a {@code Collector}. A {@code Collector} encapsulates the
* functions used as arguments to {@link #collect(Remote.Supplier,
* Remote.BiConsumer, Remote.BiConsumer)}, allowing for reuse of collection
* strategies and composition of collect operations such as multiple-level
* grouping or partitioning.
*
* If the stream is parallel, and the {@code Collector} is {@link
* RemoteCollector.Characteristics#CONCURRENT concurrent}, and either the stream
* is unordered or the collector is {@link RemoteCollector.Characteristics#UNORDERED
* unordered}, then a concurrent reduction will be performed (see {@link
* RemoteCollector} for details on concurrent reduction.)
*