com.landawn.abacus.util.stream.Stream Maven / Gradle / Ivy
Show all versions of abacus-android-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.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.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.CompletableFuture;
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.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.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.Nullable;
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.)
*
*
Stream pipelines may execute either sequentially or in
* parallel. This
* execution mode is a property of the stream. Streams are created
* with an initial choice of sequential or parallel execution. (For example,
* {@link Collection#stream() Collection.stream()} creates a sequential stream,
* and {@link Collection#parallelStream() Collection.parallelStream()} creates
* a parallel one.) This choice of execution mode may be modified by the
* {@link #sequential()} or {@link #parallel()} methods, and may be queried with
* the {@link #isParallel()} method.
*
* @param the type of the stream elements
* @since 1.8
* @see IntStream
* @see LongStream
* @see DoubleStream
* @see java.util.stream
*/
public abstract class Stream
extends StreamBase, Consumer super T>, List, Nullable, 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
*/
@ParallelSupported
public Stream select(Class targetType) {
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);
// Not efficient. Too many temporary objects will be created.
// @ParallelSupported
// public abstract EntryStream flattMapToEntry(Function super T, ? extends Collection extends V>> flatValueMapper);
@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