com.landawn.abacus.util.stream.Stream Maven / Gradle / Ivy
Show all versions of abacus-android-se-jdk7 Show documentation
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.landawn.abacus.util.stream;
import java.io.File;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import com.landawn.abacus.DataSet;
import com.landawn.abacus.DirtyMarker;
import com.landawn.abacus.annotation.Beta;
import com.landawn.abacus.exception.AbacusException;
import com.landawn.abacus.exception.UncheckedSQLException;
import com.landawn.abacus.type.Type;
import com.landawn.abacus.util.AsyncExecutor;
import com.landawn.abacus.util.ByteIterator;
import com.landawn.abacus.util.CharIterator;
import com.landawn.abacus.util.Charsets;
import com.landawn.abacus.util.ClassUtil;
import com.landawn.abacus.util.ContinuableFuture;
import com.landawn.abacus.util.DateUtil;
import com.landawn.abacus.util.DoubleIterator;
import com.landawn.abacus.util.Duration;
import com.landawn.abacus.util.FloatIterator;
import com.landawn.abacus.util.Fn;
import com.landawn.abacus.util.Fn.Suppliers;
import com.landawn.abacus.util.Holder;
import com.landawn.abacus.util.IOUtil;
import com.landawn.abacus.util.ImmutableMap;
import com.landawn.abacus.util.Indexed;
import com.landawn.abacus.util.IntIterator;
import com.landawn.abacus.util.IntList;
import com.landawn.abacus.util.Keyed;
import com.landawn.abacus.util.LineIterator;
import com.landawn.abacus.util.ListMultimap;
import com.landawn.abacus.util.LongIterator;
import com.landawn.abacus.util.Matrix;
import com.landawn.abacus.util.Multimap;
import com.landawn.abacus.util.MutableBoolean;
import com.landawn.abacus.util.MutableInt;
import com.landawn.abacus.util.N;
import com.landawn.abacus.util.Nth;
import com.landawn.abacus.util.ObjIterator;
import com.landawn.abacus.util.Optional;
import com.landawn.abacus.util.OptionalDouble;
import com.landawn.abacus.util.Pair;
import com.landawn.abacus.util.Percentage;
import com.landawn.abacus.util.RowIterator;
import com.landawn.abacus.util.ShortIterator;
import com.landawn.abacus.util.StringUtil;
import com.landawn.abacus.util.Try;
import com.landawn.abacus.util.function.BiConsumer;
import com.landawn.abacus.util.function.BiFunction;
import com.landawn.abacus.util.function.BiPredicate;
import com.landawn.abacus.util.function.BinaryOperator;
import com.landawn.abacus.util.function.BooleanSupplier;
import com.landawn.abacus.util.function.ByteBiFunction;
import com.landawn.abacus.util.function.ByteNFunction;
import com.landawn.abacus.util.function.ByteTriFunction;
import com.landawn.abacus.util.function.CharBiFunction;
import com.landawn.abacus.util.function.CharNFunction;
import com.landawn.abacus.util.function.CharTriFunction;
import com.landawn.abacus.util.function.Consumer;
import com.landawn.abacus.util.function.DoubleBiFunction;
import com.landawn.abacus.util.function.DoubleNFunction;
import com.landawn.abacus.util.function.DoubleTriFunction;
import com.landawn.abacus.util.function.FloatBiFunction;
import com.landawn.abacus.util.function.FloatNFunction;
import com.landawn.abacus.util.function.FloatTriFunction;
import com.landawn.abacus.util.function.Function;
import com.landawn.abacus.util.function.IntBiFunction;
import com.landawn.abacus.util.function.IntFunction;
import com.landawn.abacus.util.function.IntNFunction;
import com.landawn.abacus.util.function.IntTriFunction;
import com.landawn.abacus.util.function.LongBiFunction;
import com.landawn.abacus.util.function.LongFunction;
import com.landawn.abacus.util.function.LongNFunction;
import com.landawn.abacus.util.function.LongTriFunction;
import com.landawn.abacus.util.function.Predicate;
import com.landawn.abacus.util.function.ShortBiFunction;
import com.landawn.abacus.util.function.ShortNFunction;
import com.landawn.abacus.util.function.ShortTriFunction;
import com.landawn.abacus.util.function.Supplier;
import com.landawn.abacus.util.function.ToByteFunction;
import com.landawn.abacus.util.function.ToCharFunction;
import com.landawn.abacus.util.function.ToDoubleFunction;
import com.landawn.abacus.util.function.ToFloatFunction;
import com.landawn.abacus.util.function.ToIntFunction;
import com.landawn.abacus.util.function.ToLongFunction;
import com.landawn.abacus.util.function.ToShortFunction;
import com.landawn.abacus.util.function.TriFunction;
import com.landawn.abacus.util.function.UnaryOperator;
import com.landawn.abacus.util.stream.ObjIteratorEx.QueuedIterator;
/**
* Note: It's copied from OpenJDK at: http://hg.openjdk.java.net/jdk8u/hs-dev/jdk,
* And including methods copied from StreamEx: https://github.com/amaembo/streamex under Apache License, version 2.0.
*
*
*
* It's designed to service your purposes: Do what you want and returns what you expected. Try the best to adopt the the design principles of Java 8 Stream APIs, but won't has to obey every rule.
*
*
* A sequence of elements supporting sequential and parallel aggregate
* operations. The following example illustrates an aggregate operation using
* {@link Stream} and {@link IntStream}:
*
* {@code
* int sum = widgets.stream()
* .filter(w -> w.getColor() == RED)
* .mapToInt(w -> w.getWeight())
* .sum();
* }
*
* In this example, {@code widgets} is a {@code Collection}. We create
* a stream of {@code Widget} objects via {@link Collection#stream Collection.stream()},
* filter it to produce a stream containing only the red widgets, and then
* transform it into a stream of {@code int} values representing the weight of
* each red widget. Then this stream is summed to produce a total weight.
*
* In addition to {@code Stream}, which is a stream of object references,
* there are primitive specializations for {@link IntStream}, {@link LongStream},
* and {@link DoubleStream}, all of which are referred to as "streams" and
* conform to the characteristics and restrictions described here.
*
*
To perform a computation, stream
* operations are composed into a
* stream pipeline. A stream pipeline consists of a source (which
* might be an array, a collection, a generator function, an I/O channel,
* etc), zero or more intermediate operations (which transform a
* stream into another stream, such as {@link Stream#filter(Predicate)}), and a
* terminal operation (which produces a result or side-effect, such
* as {@link Stream#count()} or {@link Stream#forEach(Consumer)}).
* Streams are lazy; computation on the source data is only performed when the
* terminal operation is initiated, and source elements are consumed only
* as needed.
*
*
Collections and streams, while bearing some superficial similarities,
* have different goals. Collections are primarily concerned with the efficient
* management of, and access to, their elements. By contrast, streams do not
* provide a means to directly access or manipulate their elements, and are
* instead concerned with declaratively describing their source and the
* computational operations which will be performed in aggregate on that source.
* However, if the provided stream operations do not offer the desired
* functionality, the {@link #iterator()} and {@link #spliterator()} operations
* can be used to perform a controlled traversal.
*
*
A stream pipeline, like the "widgets" example above, can be viewed as
* a query on the stream source. Unless the source was explicitly
* designed for concurrent modification (such as a {@link ConcurrentHashMap}),
* unpredictable or erroneous behavior may result from modifying the stream
* source while it is being queried.
*
*
Most stream operations accept parameters that describe user-specified
* behavior, such as the lambda expression {@code w -> w.getWeight()} passed to
* {@code mapToInt} in the example above. To preserve correct behavior,
* these behavioral parameters:
*
* - must be non-interfering
* (they do not modify the stream source); and
* - in most cases must be stateless
* (their result should not depend on any state that might change during execution
* of the stream pipeline).
*
*
* Such parameters are always instances of a
* functional interface such
* as {@link java.util.function.Function}, and are often lambda expressions or
* method references. Unless otherwise specified these parameters must be
* non-null.
*
*
A stream should be operated on (invoking an intermediate or terminal stream
* operation) only once. This rules out, for example, "forked" streams, where
* the same source feeds two or more pipelines, or multiple traversals of the
* same stream. A stream implementation may throw {@link IllegalStateException}
* if it detects that the stream is being reused. However, since some stream
* operations may return their receiver rather than a new stream object, it may
* not be possible to detect reuse in all cases.
*
*
Streams have a {@link #close()} method and implement {@link AutoCloseable},
* but nearly all stream instances do not actually need to be closed after use.
* Generally, only streams whose source is an IO channel (such as those returned
* by {@link Files#lines(Path, Charset)}) will require closing. Most streams
* are backed by collections, arrays, or generating functions, which require no
* special resource management. (If a stream does require closing, it can be
* declared as a resource in a {@code try}-with-resources statement.)
*
*
* @param the type of the stream elements
* @see IntStream
* @see LongStream
* @see DoubleStream
*/
public abstract class Stream
extends StreamBase, Consumer super T>, List, Optional, Indexed, ObjIterator, Stream> {
@SuppressWarnings("rawtypes")
private static final Stream EMPTY = new ArrayStream(N.EMPTY_OBJECT_ARRAY, true, NATURAL_COMPARATOR, null);
Stream(final boolean sorted, final Comparator super T> cmp, final Collection closeHandlers) {
super(sorted, cmp, closeHandlers);
}
/**
*
* @param seed initial value to check if the value match the condition.
* @param predicate
* @return
*/
@ParallelSupported
public abstract Stream filter(final U seed, final BiPredicate super T, ? super U> predicate);
/**
*
* @param seed initial value to check if the value match the condition.
* @param predicate
* @return
*/
@ParallelSupported
public abstract Stream takeWhile(final U seed, final BiPredicate super T, ? super U> predicate);
/**
*
* @param seed initial value to check if the value match the condition.
* @param predicate
* @return
*/
@ParallelSupported
public abstract Stream dropWhile(final U seed, final BiPredicate super T, ? super U> predicate);
/**
* Returns a stream consisting of the remaining elements of this stream
* after removing and consuming until the specified predicate
return false.
* If there is no more elements then an empty stream will be returned.
*
* @param seed
* @param predicate
* @param consumer
* @return {@link #dropWhile(Object, BiPredicate)}
*/
@ParallelSupported
public abstract Stream dropWhile(final U seed, final BiPredicate super T, ? super U> predicate, final Consumer super T> consumer);
@ParallelSupported
public abstract Stream removeIf(final U seed, final BiPredicate super T, ? super U> predicate);
@ParallelSupported
public abstract Stream removeIf(final U seed, final BiPredicate super T, ? super U> predicate, final Consumer super T> consumer);
/**
* Returns a stream consisting of the elements in this stream which are
* instances of given class.
*
* @param targetType
* @return
*/
@SequentialOnly
public Stream select(Class targetType) {
if (isParallel()) {
return (Stream) sequential().filter(Fn.instanceOf(targetType)).parallel(maxThreadNum(), splitor());
} else {
return (Stream) filter(Fn.instanceOf(targetType));
}
}
/**
* 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 element type of the new stream
* @param mapper a non-interfering,
* stateless
* function to apply to each element
* @return the new stream
*/
@ParallelSupported
public abstract Stream map(Function super T, ? extends R> mapper);
@ParallelSupported
public abstract Stream map(U seed, BiFunction super T, ? super U, ? extends R> mapper);
// public abstract Stream biMap(BiFunction super T, ? super T, ? extends R> mapper);
//
// /**
// * Returns a stream consisting of the results of applying the given function
// * to the every two adjacent elements of this stream.
// *
// *
// *
// * Stream.of("a", "b", "c", "d", "e").biMap((i, j) -> i + "-" + j).println();
// * // print out: [a-b, c-d, e-null]
// *
// *
// *
// * @param mapper
// * @param ignoreNotPaired flag to identify if need to ignore the last element when the total length of the stream is odd number. Default value is false
// * @return
// */
// public abstract Stream biMap(BiFunction super T, ? super T, ? extends R> mapper, boolean ignoreNotPaired);
//
// public abstract Stream triMap(TriFunction super T, ? super T, ? super T, ? extends R> mapper);
//
// /**
// * Returns a stream consisting of the results of applying the given function
// * to the every three adjacent elements of this stream.
// *
// *
// *
// * Stream.of("a", "b", "c", "d", "e").triMap((i, j, k) -> i + "-" + j + "-" + k).println();
// * // print out: [a-b-c, d-e-null]
// *
// *
// *
// * @param mapper
// * @param ignoreNotPaired flag to identify if need to ignore the last one or two elements when the total length of the stream is not multiple of 3. Default value is false
// * @return
// */
// public abstract Stream triMap(TriFunction super T, ? super T, ? super T, ? extends R> mapper, boolean ignoreNotPaired);
@ParallelSupported
public abstract Stream slidingMap(BiFunction super T, ? super T, R> mapper);
/**
* Slide with windowSize = 2
and the specified increment
, then map
by the specified mapper
.
*
* @param mapper
* @param increment
* @return
*/
@ParallelSupported
public abstract Stream slidingMap(BiFunction super T, ? super T, R> mapper, int increment);
@ParallelSupported
public abstract Stream slidingMap(BiFunction super T, ? super T, R> mapper, int increment, boolean ignoreNotPaired);
@ParallelSupported
public abstract Stream slidingMap(TriFunction super T, ? super T, ? super T, R> mapper);
/**
* Slide with windowSize = 3
and the specified increment
, then map
by the specified mapper
.
*
* @param mapper
* @param increment
* @return
*/
@ParallelSupported
public abstract Stream slidingMap(TriFunction super T, ? super T, ? super T, R> mapper, int increment);
@ParallelSupported
public abstract Stream slidingMap(TriFunction super T, ? super T, ? super T, R> mapper, int increment, boolean ignoreNotPaired);
/**
* Note: copied from StreamEx: https://github.com/amaembo/streamex
*
*
*
* Returns a stream consisting of results of applying the given function to
* the ranges created from the source elements.
*
*
*
* Stream.of("a", "ab", "ac", "b", "c", "cb").rangeMap((a, b) -> b.startsWith(a), (a, b) -> a + "->" + b).toList(); // a->ac, b->b, c->cb
*
*
*
*
* This is a quasi-intermediate
* partial reduction operation.
*
* @param the type of the resulting elements
* @param sameRange a non-interfering, stateless predicate to apply to
* the leftmost and next elements which returns true for elements
* which belong to the same range.
* @param mapper a non-interfering, stateless function to apply to the
* range borders and produce the resulting element. If value was
* not merged to the interval, then mapper will receive the same
* value twice, otherwise it will receive the leftmost and the
* rightmost values which were merged to the range.
* @return the new stream
* @see #collapse(BiPredicate, BinaryOperator)
*/
@SequentialOnly
public abstract Stream rangeMap(final BiPredicate super T, ? super T> sameRange, final BiFunction super T, ? super T, ? extends U> mapper);
@ParallelSupported
public abstract Stream mapFirst(Function super T, ? extends T> mapperForFirst);
@ParallelSupported
public abstract Stream mapFirstOrElse(Function super T, ? extends R> mapperForFirst, Function super T, ? extends R> mapperForElse);
@ParallelSupported
public abstract Stream mapLast(Function super T, ? extends T> mapperForLast);
@ParallelSupported
public abstract Stream mapLastOrElse(Function super T, ? extends R> mapperForLast, Function super T, ? extends R> mapperForElse);
@ParallelSupported
public abstract CharStream mapToChar(ToCharFunction super T> mapper);
@ParallelSupported
public abstract ByteStream mapToByte(ToByteFunction super T> mapper);
@ParallelSupported
public abstract ShortStream mapToShort(ToShortFunction 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
*/
@ParallelSupported
public abstract IntStream mapToInt(ToIntFunction 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
*/
@ParallelSupported
public abstract LongStream mapToLong(ToLongFunction super T> mapper);
@ParallelSupported
public abstract FloatStream mapToFloat(ToFloatFunction 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
*/
@ParallelSupported
public abstract DoubleStream mapToDouble(ToDoubleFunction super T> mapper);
// public abstract EntryStream mapToEntry();
@ParallelSupported
public abstract EntryStream mapToEntry(Function super T, ? extends Map.Entry> mapper);
@ParallelSupported
public abstract EntryStream mapToEntry(Function super T, K> keyMapper, Function super T, V> valueMapper);
/**
* 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.
*
* This is an intermediate
* operation.
*
* @apiNote
* The {@code flatMap()} operation has the effect of applying a one-to-many
* transformation to the elements of the stream, and then flattening the
* resulting elements into a new stream.
*
*
Examples.
*
*
If {@code orders} is a stream of purchase orders, and each purchase
* order contains a collection of line items, then the following produces a
* stream containing all the line items in all the orders:
*
{@code
* orders.flatMap(order -> order.getLineItems().stream())...
* }
*
* If {@code path} is the path to a file, then the following produces a
* stream of the {@code words} contained in that file:
*
{@code
* Stream lines = Files.lines(path, StandardCharsets.UTF_8);
* Stream words = lines.flatMap(line -> Stream.of(line.split(" +")));
* }
* The {@code mapper} function passed to {@code flatMap} splits a line,
* using a simple regular expression, into an array of words, and then
* creates a stream of words from that array.
*
* @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
*/
@ParallelSupported
public abstract Stream flatMap(Function super T, ? extends Stream extends R>> mapper);
@ParallelSupported
public abstract Stream flatMap(U seed, BiFunction super T, ? super U, ? extends Stream extends R>> mapper);
@ParallelSupported
public abstract Stream flattMap(Function super T, ? extends Collection extends R>> mapper);
@ParallelSupported
public abstract Stream flattMap(U seed, BiFunction super T, ? super U, ? extends Collection extends R>> mapper);
@ParallelSupported
public abstract Stream flatMapp(Function super T, R[]> mapper);
@ParallelSupported
public abstract Stream flatMapp(U seed, BiFunction super T, ? super U, R[]> mapper);
@ParallelSupported
public abstract CharStream flatMapToChar(Function super T, ? extends CharStream> mapper);
@ParallelSupported
public abstract ByteStream flatMapToByte(Function super T, ? extends ByteStream> mapper);
@ParallelSupported
public abstract ShortStream flatMapToShort(Function super T, ? extends ShortStream> 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 java.util.stream.Baseclose() 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)
*/
@ParallelSupported
public abstract IntStream flatMapToInt(Function super T, ? extends IntStream> 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 java.util.stream.Baseclose() 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)
*/
@ParallelSupported
public abstract LongStream flatMapToLong(Function super T, ? extends LongStream> mapper);
@ParallelSupported
public abstract FloatStream flatMapToFloat(Function super T, ? extends FloatStream> 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 java.util.stream.Baseclose() closed} after its
* contents have placed been 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)
*/
@ParallelSupported
public abstract DoubleStream flatMapToDouble(Function super T, ? extends DoubleStream> mapper);
@ParallelSupported
public abstract EntryStream flatMapToEntry(Function super T, ? extends Stream extends Map.Entry>> mapper);
@ParallelSupported
public abstract EntryStream flattMapToEntry(Function super T, ? extends Map> mapper);
@ParallelSupported
public abstract EntryStream flatMappToEntry(Function super T, ? extends EntryStream> mapper);
@ParallelSupported
public abstract Stream>> groupBy(final Function super T, ? extends K> classifier);
@ParallelSupported
public abstract Stream>> groupBy(final Function super T, ? extends K> classifier,
final Supplier extends Map>> mapFactory);
/**
*
* @param classifier
* @param valueMapper
* @return
* @see Collectors#toMultimap(Function, Function)
*/
@ParallelSupported
public abstract Stream>> groupBy(Function super T, ? extends K> classifier, Function super T, ? extends U> valueMapper);
/**
*
* @param classifier
* @param valueMapper
* @param mapFactory
* @return
* @see Collectors#toMultimap(Function, Function, Supplier)
*/
@ParallelSupported
public abstract Stream>> groupBy(Function super T, ? extends K> classifier, Function super T, ? extends U> valueMapper,
Supplier extends Map>> mapFactory);
@ParallelSupported
public abstract Stream> groupBy(final Function super T, ? extends K> classifier, final Collector super T, A, D> downstream);
@ParallelSupported
public abstract Stream> groupBy(final Function super T, ? extends K> classifier, final Collector super T, A, D> downstream,
final Supplier extends Map> mapFactory);
@ParallelSupported
public abstract Stream> groupBy(final Function super T, ? extends K> classifier,
final Function super T, ? extends U> valueMapper, final Collector super U, A, D> downstream);
@ParallelSupported
public abstract Stream> groupBy(final Function super T, ? extends K> classifier,
final Function super T, ? extends U> valueMapper, final Collector super U, A, D> downstream, final Supplier extends Map> mapFactory);
@ParallelSupported
public abstract Stream> groupBy(final Function super T, ? extends K> classifier,
final Function super T, ? extends V> valueMapper, BinaryOperator mergeFunction);
@ParallelSupported
public abstract Stream> groupBy(final Function super T, ? extends K> classifier,
final Function super T, ? extends V> valueMapper, final BinaryOperator mergeFunction, final Supplier extends Map> mapFactory);
/**
*
* @param predicate
* @return
* @see Collectors#partitioningBy(Predicate)
*/
@ParallelSupported
public abstract Stream>> partitionBy(final Predicate super T> predicate);
/**
*
* @param predicate
* @param downstream
* @return
* @see Collectors#partitioningBy(Predicate, Collector)
*/
@ParallelSupported
public abstract Stream> partitionBy(final Predicate super T> predicate, final Collector super T, A, D> downstream);
@ParallelSupported
public Stream> countBy(final Function super T, ? extends K> classifier) {
return groupBy(classifier, Collectors.countingInt());
}
@ParallelSupported
public abstract EntryStream> groupByToEntry(final Function super T, ? extends K> classifier);
@ParallelSupported
public abstract EntryStream> groupByToEntry(final Function super T, ? extends K> classifier,
final Supplier extends Map>> mapFactory);
/**
*
* @param classifier
* @param valueMapper
* @return
* @see Collectors#toMultimap(Function, Function)
*/
@ParallelSupported
public abstract EntryStream> groupByToEntry(Function super T, ? extends K> classifier, Function super T, ? extends U> valueMapper);
/**
*
* @param classifier
* @param valueMapper
* @param mapFactory
* @return
* @see Collectors#toMultimap(Function, Function, Supplier)
*/
@ParallelSupported
public abstract EntryStream> groupByToEntry(Function super T, ? extends K> classifier, Function super T, ? extends U> valueMapper,
Supplier extends Map>> mapFactory);
@ParallelSupported
public abstract EntryStream groupByToEntry(final Function super T, ? extends K> classifier, final Collector super T, A, D> downstream);
@ParallelSupported
public abstract EntryStream groupByToEntry(final Function super T, ? extends K> classifier, final Collector super T, A, D> downstream,
final Supplier extends Map> mapFactory);
@ParallelSupported
public abstract EntryStream groupByToEntry(final Function super T, ? extends K> classifier,
final Function super T, ? extends U> valueMapper, final Collector super U, A, D> downstream);
@ParallelSupported
public abstract EntryStream groupByToEntry(final Function super T, ? extends K> classifier,
final Function super T, ? extends U> valueMapper, final Collector super U, A, D> downstream, final Supplier extends Map> mapFactory);
@ParallelSupported
public abstract EntryStream groupByToEntry(final Function super T, ? extends K> classifier,
final Function super T, ? extends U> valueMapper, BinaryOperator mergeFunction);
@ParallelSupported
public abstract EntryStream groupByToEntry(final Function super T, ? extends K> classifier,
final Function super T, ? extends V> valueMapper, final BinaryOperator mergeFunction, final Supplier extends Map> mapFactory);
/**
*
* @param predicate
* @return
* @see Collectors#partitioningBy(Predicate)
*/
@ParallelSupported
public abstract EntryStream> partitionByToEntry(final Predicate super T> predicate);
/**
*
* @param predicate
* @param downstream
* @return
* @see Collectors#partitioningBy(Predicate, Collector)
*/
@ParallelSupported
public abstract EntryStream partitionByToEntry(final Predicate super T> predicate, final Collector super T, A, D> downstream);
@ParallelSupported
public EntryStream countByToEntry(final Function super T, ? extends K> classifier) {
return groupByToEntry(classifier, Collectors.countingInt());
}
/**
* Merge series of adjacent elements which satisfy the given predicate using
* the merger function and return a new stream.
*
* Example:
*
*
* Stream.of(new Integer[0]).collapse((a, b) -> a < b, (a, b) -> a + b) => []
* Stream.of(1).collapse((a, b) -> a < b, (a, b) -> a + b) => [1]
* Stream.of(1, 2).collapse((a, b) -> a < b, (a, b) -> a + b) => [3]
* Stream.of(1, 2, 3).collapse((a, b) -> a < b, (a, b) -> a + b) => [6]
* Stream.of(1, 2, 3, 3, 2, 1).collapse((a, b) -> a < b, (a, b) -> a + b) => [6, 3, 2, 1]
*
*
*
*
* This method only run sequentially, even in parallel stream.
*
* @param collapsible
* @param mergeFunction
* @return
*/
@SequentialOnly
public abstract Stream collapse(final BiPredicate super T, ? super T> collapsible, final BiFunction super T, ? super T, T> mergeFunction);
@SequentialOnly
public abstract Stream collapse(final BiPredicate super T, ? super T> collapsible, final Supplier supplier,
final BiConsumer accumulator);
/**
* Merge series of adjacent elements which satisfy the given predicate using
* the merger function and return a new stream.
*
* Example:
*
*
* Stream.of(new Integer[0]).collapse((a, b) -> a < b, Collectors.summingInt(Fn.unboxI())) => []
* Stream.of(1).collapse((a, b) -> a < b, Collectors.summingInt(Fn.unboxI())) => [1]
* Stream.of(1, 2).collapse((a, b) -> a < b, Collectors.summingInt(Fn.unboxI())) => [3]
* Stream.of(1, 2, 3).collapse((a, b) -> a < b, Collectors.summingInt(Fn.unboxI())) => [6]
* Stream.of(1, 2, 3, 3, 2, 1).collapse((a, b) -> a < b, Collectors.summingInt(Fn.unboxI())) => [6, 3, 2, 1]
*
*
*
*
* This method only run sequentially, even in parallel stream.
*
* @param collapsible
* @param collector
* @return
*/
@SequentialOnly
public abstract Stream collapse(final BiPredicate super T, ? super T> collapsible, final Collector super T, A, R> collector);
/**
* Returns a {@code Stream} produced by iterative application of a accumulation function
* to an initial element {@code seed} and next element of the current stream.
* Produces a {@code Stream} consisting of {@code seed}, {@code acc(seed, value1)},
* {@code acc(acc(seed, value1), value2)}, etc.
*
* This is an intermediate operation.
*
*
Example:
*
*
* Stream.of(new Integer[0]).scan((a, b) -> a + b) => []
* Stream.of(1).scan((a, b) -> a + b) => [1]
* Stream.of(1, 2).scan((a, b) -> a + b) => [1, 3]
* Stream.of(1, 2, 3).scan((a, b) -> a + b) => [1, 3, 6]
* Stream.of(1, 2, 3, 3, 2, 1).scan((a, b) -> a + b) => [1, 3, 6, 9, 11, 12]
*
*
*
*
* This method only run sequentially, even in parallel stream.
*
* @param accumulator the accumulation function
* @return the new stream which has the extract same size as this stream.
*/
@SequentialOnly
public abstract Stream scan(final BiFunction super T, ? super T, T> accumulator);
/**
* Returns a {@code Stream} produced by iterative application of a accumulation function
* to an initial element {@code seed} and next element of the current stream.
* Produces a {@code Stream} consisting of {@code seed}, {@code acc(seed, value1)},
* {@code acc(acc(seed, value1), value2)}, etc.
*
* This is an intermediate operation.
*
*
Example:
*
*
* Stream.of(new Integer[0]).scan(10, (a, b) -> a + b) => []
* Stream.of(1).scan(10, (a, b) -> a + b) => [11]
* Stream.of(1, 2).scan(10, (a, b) -> a + b) => [11, 13]
* Stream.of(1, 2, 3).scan(10, (a, b) -> a + b) => [11, 13, 16]
* Stream.of(1, 2, 3, 3, 2, 1).scan(10, (a, b) -> a + b) => [11, 13, 16, 19, 21, 22]
*
*
*
*
* This method only run sequentially, even in parallel stream.
*
* @param seed the initial value. it's only used once by accumulator
to calculate the fist element in the returned stream.
* It will be ignored if this stream is empty and won't be the first element of the returned stream.
*
* @param accumulator the accumulation function
* @return the new stream which has the extract same size as this stream.
*/
@SequentialOnly
public abstract Stream scan(final R seed, final BiFunction super R, ? super T, R> accumulator);
/**
* Returns Stream of Stream with consecutive sub sequences of the elements, each of the same size (the final sequence may be smaller).
*
*
* This method only run sequentially, even in parallel stream.
*
* @param size
* @return
*/
@SequentialOnly
public abstract Stream> splitToSet(int size);
@SequentialOnly
public abstract Stream> splitToSet(Predicate super T> predicate);
/**
* Split the stream by the specified predicate.
*
*
*
* // split the number sequence by window 5.
* Stream.of(1, 2, 3, 5, 7, 9, 10, 11, 19).splitToSet(MutableInt.of(5), (e, b) -> e <= b.intValue(), b -> b.addAndGet(5)).forEach(N::println);
*
*
*
*
* This method only run sequentially, even in parallel stream.
*
* @param seed
* @param predicate
* @param seedUpdate
* @return
*/
@SequentialOnly
public abstract Stream> splitToSet(U seed, BiPredicate super T, ? super U> predicate, Consumer super U> seedUpdate);
/**
* Returns Stream of Stream with consecutive sub sequences of the elements, each of the same size (the final sequence may be smaller).
*
*
* This method only run sequentially, even in parallel stream.
*
* @param size
* @param collectionSupplier
* @return
*/
@SequentialOnly
public abstract > Stream split(int size, IntFunction collectionSupplier);
@SequentialOnly
public abstract > Stream split(Predicate super T> predicate, Supplier collectionSupplier);
/**
* Split the stream by the specified predicate.
*
*
*
* // split the number sequence by window 5.
* Stream.of(1, 2, 3, 5, 7, 9, 10, 11, 19).split(MutableInt.of(5), (e, b) -> e <= b.intValue(), b -> b.addAndGet(5), Suppliers.ofList).forEach(N::println);
*
*
*
*
* This method only run sequentially, even in parallel stream.
*
* @param seed
* @param predicate
* @param seedUpdate
* @param collectionSupplier
* @return
*/
@SequentialOnly
public abstract > Stream split(U seed, BiPredicate super T, ? super U> predicate, Consumer super U> seedUpdate,
Supplier collectionSupplier);
@SequentialOnly
public abstract > Stream sliding(int windowSize, IntFunction collectionSupplier);
@SequentialOnly
public abstract > Stream sliding(int windowSize, int increment, IntFunction collectionSupplier);
/**
* Stream.of(1).intersperse(9) --> [1]
* Stream.of(1, 2, 3).intersperse(9) --> [1, 9, 2, 9, 3]
*
*
* This method only run sequentially, even in parallel stream.
*
* @param delimiter
* @return
*/
@SequentialOnly
public abstract Stream intersperse(T delimiter);
/**
* Distinct and filter by occurrences.
*
* @param occurrencesFilter
* @return
*/
@ParallelSupported
public Stream distinct(final Predicate super Long> occurrencesFilter) {
final Supplier extends Map> supplier = isParallel() ? Suppliers. ofConcurrentHashMap() : Suppliers. ofLinkedHashMap();
return groupBy(Fn. identity(), Collectors.counting(), supplier).filter(Fn. testByValue(occurrencesFilter)).map(Fn. key());
}
/**
* Distinct by the value mapped from keyExtractor
*
* @param keyExtractor don't change value of the input parameter.
* @return
*/
@ParallelSupported
public abstract Stream distinctBy(Function super T, ?> keyExtractor);
/**
* Distinct and filter by occurrences.
*
* @param keyExtractor
* @param occurrencesFilter
* @return
*/
public Stream distinctBy(final Function super T, K> keyExtractor, final Predicate super Long> occurrencesFilter) {
final Supplier extends Map, Long>> supplier = isParallel() ? Suppliers., Long> ofConcurrentHashMap()
: Suppliers., Long> ofLinkedHashMap();
return groupBy(Fn. keyed(keyExtractor), Collectors.counting(), supplier).filter(Fn., Long> testByValue(occurrencesFilter))
.map(Fn. kk());
}
/**
*
*
* This method only run sequentially, even in parallel stream.
*
* @param n
* @return
*/
@SequentialOnly
public abstract Stream top(int n);
/**
*
* This method only run sequentially, even in parallel stream.
*
* @param n
* @param comparator
* @return
*/
@SequentialOnly
public abstract Stream top(int n, 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
*/
@ParallelSupported
public abstract Stream sorted(Comparator super T> comparator);
@SuppressWarnings("rawtypes")
@ParallelSupported
public abstract Stream sortedBy(Function super T, ? extends Comparable> keyExtractor);
@ParallelSupported
public abstract Stream sortedByInt(ToIntFunction super T> keyExtractor);
@ParallelSupported
public abstract Stream sortedByLong(ToLongFunction super T> keyExtractor);
@ParallelSupported
public abstract Stream sortedByDouble(ToDoubleFunction super T> keyExtractor);
@ParallelSupported
public abstract void forEach(Try.Consumer super T, E> action) throws E;
@ParallelSupported
public abstract void forEachPair(final Try.BiConsumer super T, ? super T, E> action) throws E;
/**
* Slide with windowSize = 2
and the specified increment
, then consume
by the specified mapper
.
*
* @param mapper
* @param increment
* @return
*/
@ParallelSupported
public abstract void forEachPair(final Try.BiConsumer super T, ? super T, E> action, final int increment) throws E;
@ParallelSupported
public abstract void forEachTriple(final Try.TriConsumer super T, ? super T, ? super T, E> action) throws E;
/**
* Slide with windowSize = 3
and the specified increment
, then consume
by the specified mapper
.
*
* @param mapper
* @param increment
* @return
*/
@ParallelSupported
public abstract void forEachTriple(final Try.TriConsumer super T, ? super T, ? super T, E> action, final int increment) throws E;
@ParallelSupported
public abstract boolean anyMatch(Try.Predicate super T, E> predicate) throws E;
@ParallelSupported
public abstract boolean allMatch(Try.Predicate super T, E> predicate) throws E;
@ParallelSupported
public abstract boolean noneMatch(Try.Predicate super T, E> predicate) throws E;
@ParallelSupported
public abstract Optional findFirst(Try.Predicate super T, E> predicate) throws E;
@ParallelSupported
public abstract Optional findLast(Try.Predicate super T, E> predicate) throws E;
@SequentialOnly
public abstract Optional findFirstOrLast(Try.Predicate super T, E> predicateForFirst,
Try.Predicate super T, E2> predicateForLast) throws E, E2;
@ParallelSupported
public abstract Optional findAny(Try.Predicate super T, E> predicate) throws E;
/**
*
* @param seed
* @param predicate
* @return
*/
@ParallelSupported
public abstract Optional findFirst(final U seed, final Try.BiPredicate super T, ? super U, E> predicate) throws E;
/**
*
* @param seed
* @param predicate
* @return
*/
@ParallelSupported
public abstract Optional findLast(final U seed, final Try.BiPredicate super T, ? super U, E> predicate) throws E;
/**
*
* @param seed
* @param predicate
* @return
*/
@ParallelSupported
public abstract Optional findAny(final U seed, final Try.BiPredicate super T, ? super U, E> predicate) throws E;
/**
*
* This method only run sequentially, even in parallel stream.
*
* @param seed
* @param predicateForFirst
* @param predicateForLast
* @return
*/
@SequentialOnly
public abstract Optional findFirstOrLast(final U seed,
final Try.BiPredicate super T, ? super U, E> predicateForFirst, final Try.BiPredicate super T, ? super U, E2> predicateForLast) throws E, E2;
/**
*
* This method only run sequentially, even in parallel stream.
*
* @param preFunc
* @param predicateForFirst
* @param predicateForLast
* @return
*/
@SequentialOnly
public abstract Optional findFirstOrLast(final Function super T, U> preFunc,
final Try.BiPredicate super T, ? super U, E> predicateForFirst, final Try.BiPredicate super T, ? super U, E2> predicateForLast) throws E, E2;
@ParallelSupported
public abstract boolean anyMatch(final U seed, final Try.BiPredicate super T, ? super U, E> predicate) throws E;
@ParallelSupported
public abstract boolean allMatch(final U seed, final Try.BiPredicate super T, ? super U, E> predicate) throws E;
@ParallelSupported
public abstract boolean noneMatch(final U seed, final Try.BiPredicate super T, ? super U, E> predicate) throws E;
@SequentialOnly
public abstract boolean containsAll(T... a);
@SequentialOnly
public abstract boolean containsAll(Collection extends T> c);
/**
* 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.
*
* @apiNote
* The generator function takes an integer, which is the size of the
* desired array, and produces an array of the desired size. This can be
* concisely expressed with an array constructor reference:
*
{@code
* Person[] men = people.stream()
* .filter(p -> p.getGender() == MALE)
* .toArray(Person[]::new);
* }
*
* @param the element type of the resulting array
* @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
*/
@SequentialOnly
public abstract A[] toArray(IntFunction generator);
/**
*
* @param keyExtractor
* @param valueMapper
* @return
* @see Collectors#toMap(Function, Function)
*/
@ParallelSupported
public ImmutableMap toImmutableMap(Function super T, ? extends K> keyExtractor, Function super T, ? extends V> valueMapper) {
return ImmutableMap.of(toMap(keyExtractor, valueMapper));
}
/**
*
* @param keyExtractor
* @param valueMapper
* @param mergeFunction
* @return
* @see Collectors#toMap(Function, Function)
*/
@ParallelSupported
public ImmutableMap toImmutableMap(Function super T, ? extends K> keyExtractor, Function super T, ? extends V> valueMapper,
BinaryOperator mergeFunction) {
return ImmutableMap.of(toMap(keyExtractor, valueMapper, mergeFunction));
}
/**
*
* @param keyExtractor
* @param valueMapper
* @return
* @see Collectors#toMap(Function, Function)
*/
@ParallelSupported
public abstract Map toMap(Function super T, ? extends K> keyExtractor, Function super T, ? extends V> valueMapper);
/**
*
* @param keyExtractor
* @param valueMapper
* @param mergeFunction
* @return
* @see Collectors#toMap(Function, Function, BinaryOperator)
*/
@ParallelSupported
public abstract Map toMap(Function super T, ? extends K> keyExtractor, Function super T, ? extends V> valueMapper,
BinaryOperator mergeFunction);
/**
*
* @param keyExtractor
* @param valueMapper
* @param mapFactory
* @return
* @see Collectors#toMap(Function, Function, Supplier)
*/
@ParallelSupported
public abstract > M toMap(Function super T, ? extends K> keyExtractor, Function super T, ? extends V> valueMapper,
Supplier mapFactory);
/**
*
* @param keyExtractor
* @param valueMapper
* @param mergeFunction
* @param mapFactory
* @return
* @see Collectors#toMap(Function, Function, BinaryOperator, Supplier)
*/
@ParallelSupported
public abstract > M toMap(Function super T, ? extends K> keyExtractor, Function super T, ? extends V> valueMapper,
BinaryOperator mergeFunction, Supplier mapFactory);
/**
*
* @param classifier
* @param downstream
* @return
* @see Collectors#groupingBy(Function, Collector)
*/
@ParallelSupported
public abstract