All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tangosol.util.stream.RemoteStream Maven / Gradle / Ivy

/*
 * 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.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>
    {
    /**
     * 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 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 predicate) { return filter((Predicate) 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 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 mapper) { return map((Function) 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 mapper) { return map((Function) 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 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 mapper) { return mapToInt((ToIntFunction) 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 mapper) { return mapToInt((ToIntFunction) 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 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 mapper) { return mapToLong((ToLongFunction) 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 mapper) { return mapToLong((ToLongFunction) 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 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 mapper) { return mapToDouble((ToDoubleFunction) 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 mapper) { return mapToDouble((ToDoubleFunction) 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> 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> mapper) { Function> 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 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 mapper) { Function 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 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 mapper) { Function 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 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 mapper) { Function 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 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 action) { return peek((Consumer) 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 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 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 comparator, boolean fInverse) { Comparator 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 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 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 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 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 collector) { if (collector instanceof RemoteCollector) { return collect((RemoteCollector) 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.) *

* This is a terminal operation. * * @param the type of the result * @param the intermediate accumulation type of the Collector * @param collector the {@code Collector} describing the reduction * * @return the result of the reduction * * @see #collect(Remote.Supplier, Remote.BiConsumer, Remote.BiConsumer) */ R collect(RemoteCollector collector); /** * Returns the minimum element of this stream according to the provided * {@code Comparator}. This is a special case of a reduction. *

* This is a terminal operation. * * @param comparator a non-interfering, stateless {@code Comparator} to * compare elements of this stream * * @return an {@code Optional} describing the minimum element of this * stream, or an empty {@code Optional} if the stream is empty */ Optional min(Comparator comparator); /** * Returns the minimum element of this stream according to the provided * {@code Comparator}. This is a special case of a reduction. *

* This is a terminal operation. * * @param comparator a non-interfering, stateless {@code Comparator} to * compare elements of this stream * * @return an {@code Optional} describing the minimum element of this * stream, or an empty {@code Optional} if the stream is empty */ default Optional min(Remote.Comparator comparator) { return min((Comparator) comparator); } /** * Returns the minimum element of this stream according to the attribute * extracted by the provided {@code ValueExtractor}. This is a special case of a reduction. *

* This is a terminal 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 an {@code Optional} describing the minimum element of this * stream, or an empty {@code Optional} if the stream is empty */ default Optional min(ValueExtractor extractor) { return min(new ExtractorComparator(extractor)); } /** * Returns the maximum element of this stream according to the provided * {@code Comparator}. This is a special case of a reduction. *

* This is a terminal operation. * * @param comparator a non-interfering, stateless {@code Comparator} to * compare elements of this stream * * @return an {@code Optional} describing the maximum element of this * stream, or an empty {@code Optional} if the stream is empty */ Optional max(Comparator comparator); /** * Returns the maximum element of this stream according to the provided * {@code Comparator}. This is a special case of a reduction. *

* This is a terminal operation. * * @param comparator a non-interfering, stateless {@code Comparator} to * compare elements of this stream * * @return an {@code Optional} describing the maximum element of this * stream, or an empty {@code Optional} if the stream is empty */ default Optional max(Remote.Comparator comparator) { return max((Comparator) comparator); } /** * Returns the maximum element of this stream according to the attribute * extracted by the provided {@code ValueExtractor}. This is a special case of a reduction. *

* This is a terminal 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 an {@code Optional} describing the maximum element of this * stream, or an empty {@code Optional} if the stream is empty */ default Optional max(ValueExtractor extractor) { return max(new ExtractorComparator(extractor)); } /** * Returns the count of elements in this stream. This is a special case of * a reduction and is equivalent to: *

{@code
     *     return mapToLong(e -> 1L).sum();
     * }
*

* This is a terminal operation. * * @return the count of elements in this stream */ long count(); /** * Returns whether any elements of this stream match the provided predicate. * May not evaluate the predicate on all elements if not necessary for * determining the result. *

* This is a short-circuiting terminal operation. * * @param predicate a non-interfering, stateless predicate to apply to * elements of this stream * * @return {@code true} if any elements of the stream match the provided * predicate, otherwise {@code false} */ boolean anyMatch(Predicate predicate); /** * Returns whether any elements of this stream match the provided predicate. * May not evaluate the predicate on all elements if not necessary for * determining the result. *

* This is a short-circuiting terminal operation. * * @param predicate a non-interfering, stateless predicate to apply to * elements of this stream * * @return {@code true} if any elements of the stream match the provided * predicate, otherwise {@code false} */ default boolean anyMatch(Remote.Predicate predicate) { return anyMatch((Predicate) predicate); } /** * Returns whether all elements of this stream match the provided predicate. * May not evaluate the predicate on all elements if not necessary for * determining the result. *

* This is a short-circuiting terminal operation. * * @param predicate a non-interfering, stateless predicate to apply to * elements of this stream * * @return {@code true} if either all elements of the stream match the * provided predicate or the stream is empty, otherwise {@code false} */ boolean allMatch(Predicate predicate); /** * Returns whether all elements of this stream match the provided predicate. * May not evaluate the predicate on all elements if not necessary for * determining the result. *

* This is a short-circuiting terminal operation. * * @param predicate a non-interfering, stateless predicate to apply to * elements of this stream * * @return {@code true} if either all elements of the stream match the * provided predicate or the stream is empty, otherwise {@code false} */ default boolean allMatch(Remote.Predicate predicate) { return allMatch((Predicate) predicate); } /** * Returns whether no elements of this stream match the provided predicate. * May not evaluate the predicate on all elements if not necessary for * determining the result. *

* This is a short-circuiting terminal operation. * * @param predicate a non-interfering, stateless predicate to apply to * elements of this stream * * @return {@code true} if either no elements of the stream match the * provided predicate or the stream is empty, otherwise {@code false} */ boolean noneMatch(Predicate predicate); /** * Returns whether no elements of this stream match the provided predicate. * May not evaluate the predicate on all elements if not necessary for * determining the result. *

* This is a short-circuiting terminal operation. * * @param predicate a non-interfering, stateless predicate to apply to * elements of this stream * * @return {@code true} if either no elements of the stream match the * provided predicate or the stream is empty, otherwise {@code false} */ default boolean noneMatch(Remote.Predicate predicate) { return noneMatch((Predicate) predicate); } /** * Returns an {@link Optional} describing the first element of this stream, * or an empty {@code Optional} if the stream is empty. If the stream has * no encounter order, then any element may be returned. *

* This is a short-circuiting terminal operation. * * @return an {@code Optional} describing the first element of this stream, * or an empty {@code Optional} if the stream is empty * * @throws NullPointerException if the element selected is null */ Optional findFirst(); /** * Returns an {@link Optional} describing some element of the stream, or an * empty {@code Optional} if the stream is empty. *

* This is a short-circuiting terminal operation. *

* The behavior of this operation is explicitly nondeterministic; it is free * to select any element in the stream. This is to allow for maximal * performance in parallel operations; the cost is that multiple invocations * on the same source may not return the same result. (If a stable result * is desired, use {@link #findFirst()} instead.) * * @return an {@code Optional} describing some element of this stream, or an * empty {@code Optional} if the stream is empty * * @throws NullPointerException if the element selected is null * * @see #findFirst() */ Optional findAny(); // ---- helpers --------------------------------------------------------- /** * Convert stream of numbers into {@link RemoteIntStream}. * * @param the type of input stream elements * @param stream the stream of numbers * * @return a {@code RemoteIntStream} instance */ public static RemoteIntStream toIntStream(RemoteStream stream) { return stream.mapToInt(Number::intValue); } /** * Convert stream of numbers into {@link RemoteLongStream}. * * @param the type of input stream elements * @param stream the stream of numbers * * @return a {@code RemoteLongStream} instance */ public static RemoteLongStream toLongStream(RemoteStream stream) { return stream.mapToLong(Number::longValue); } /** * Convert stream of numbers into {@link RemoteDoubleStream}. * * @param the type of input stream elements * @param stream the stream of numbers * * @return a {@code RemoteDoubleStream} instance */ public static RemoteDoubleStream toDoubleStream(RemoteStream stream) { return stream.mapToDouble(Number::doubleValue); } }