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

com.landawn.abacus.util.stream.ShortStream Maven / Gradle / Ivy

There is a newer version: 1.10.1
Show newest version
/*
 * 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.util.ArrayList;
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 com.landawn.abacus.exception.AbacusException;
import com.landawn.abacus.util.CompletableFuture;
import com.landawn.abacus.util.Holder;
import com.landawn.abacus.util.IndexedShort;
import com.landawn.abacus.util.Multimap;
import com.landawn.abacus.util.MutableInt;
import com.landawn.abacus.util.N;
import com.landawn.abacus.util.Nth;
import com.landawn.abacus.util.Optional;
import com.landawn.abacus.util.OptionalDouble;
import com.landawn.abacus.util.OptionalShort;
import com.landawn.abacus.util.Pair;
import com.landawn.abacus.util.Percentage;
import com.landawn.abacus.util.ShortIterator;
import com.landawn.abacus.util.ShortList;
import com.landawn.abacus.util.ShortMatrix;
import com.landawn.abacus.util.ShortSummaryStatistics;
import com.landawn.abacus.util.function.BiConsumer;
import com.landawn.abacus.util.function.BinaryOperator;
import com.landawn.abacus.util.function.Function;
import com.landawn.abacus.util.function.ObjShortConsumer;
import com.landawn.abacus.util.function.ShortBiFunction;
import com.landawn.abacus.util.function.ShortBiPredicate;
import com.landawn.abacus.util.function.ShortBinaryOperator;
import com.landawn.abacus.util.function.ShortConsumer;
import com.landawn.abacus.util.function.ShortFunction;
import com.landawn.abacus.util.function.ShortNFunction;
import com.landawn.abacus.util.function.ShortPredicate;
import com.landawn.abacus.util.function.ShortSupplier;
import com.landawn.abacus.util.function.ShortToIntFunction;
import com.landawn.abacus.util.function.ShortTriFunction;
import com.landawn.abacus.util.function.ShortUnaryOperator;
import com.landawn.abacus.util.function.Supplier;
import com.landawn.abacus.util.function.ToShortFunction;

/**
 * Note: It's copied from OpenJDK at: http://hg.openjdk.java.net/jdk8u/hs-dev/jdk
 * 
* * A sequence of primitive int-valued elements supporting sequential and parallel * aggregate operations. This is the {@code int} primitive specialization of * {@link Stream}. * *

The following example illustrates an aggregate operation using * {@link Stream} and {@link ShortStream}, computing the sum of the weights of the * red widgets: * *

{@code
 *     int sum = widgets.stream()
 *                      .filter(w -> w.getColor() == RED)
 *                      .mapToShort(w -> w.getWeight())
 *                      .sum();
 * }
* * See the class documentation for {@link Stream} and the package documentation * for java.util.stream for additional * specification of streams, stream operations, stream pipelines, and * parallelism. * * @since 1.8 * @see Stream * @see java.util.stream */ public abstract class ShortStream extends StreamBase { private static final ShortStream EMPTY = new ArrayShortStream(N.EMPTY_SHORT_ARRAY, null, true); ShortStream(final Collection closeHandlers, final boolean sorted) { super(closeHandlers, sorted, null); } /** * 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 */ public abstract ShortStream map(ShortUnaryOperator mapper); /** * Returns a {@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 */ public abstract IntStream mapToInt(ShortToIntFunction mapper); /** * Returns an object-valued {@code 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 */ public abstract Stream mapToObj(ShortFunction 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 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 an * {@code ShortStream} of new values * @return the new stream * @see Stream#flatMap(Function) */ public abstract ShortStream flatMap(ShortFunction mapper); public abstract IntStream flatMapToInt(ShortFunction mapper); public abstract Stream flatMapToObj(ShortFunction> mapper); public abstract ShortStream collapse(final ShortBiPredicate collapsible, final ShortBiFunction mergeFunction); /** * Returns a {@code Stream} produced by iterative application of a accumulation function * to an initial element {@code identity} and next element of the current stream. * Produces a {@code Stream} consisting of {@code identity}, {@code acc(identity, value1)}, * {@code acc(acc(identity, value1), value2)}, etc. * *

This is an intermediate operation. * *

Example: *

     * identity: 0
     * accumulator: (a, b) -> a + b
     * stream: [1, 2, 3, 4, 5]
     * result: [0, 1, 3, 6, 10, 15]
     * 
* *
* 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. */ public abstract ShortStream scan(final ShortBiFunction accumulator); /** * Returns a {@code Stream} produced by iterative application of a accumulation function * to an initial element {@code identity} and next element of the current stream. * Produces a {@code Stream} consisting of {@code identity}, {@code acc(identity, value1)}, * {@code acc(acc(identity, value1), value2)}, etc. * *

This is an intermediate operation. * *

Example: *

     * seed:10
     * accumulator: (a, b) -> a + b
     * stream: [1, 2, 3, 4, 5]
     * result: [11, 13, 16, 20, 25]
     * 
* *
* 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. */ public abstract ShortStream scan(final short seed, final ShortBiFunction accumulator); public abstract ShortStream reverseSorted(); /** *
* This method only run sequentially, even in parallel stream. * * @param n * @return */ public abstract ShortStream top(int n); /** *
* This method only run sequentially, even in parallel stream. * * @param n * @return */ public abstract ShortStream top(final int n, Comparator comparator); public abstract ShortList toShortList(); /** * * @param keyExtractor * @param valueMapper * @return * @see Collectors#toMap(Function, Function) */ public abstract Map toMap(ShortFunction keyExtractor, ShortFunction valueMapper); /** * * @param keyExtractor * @param valueMapper * @param mapFactory * @return * @see Collectors#toMap(Function, Function, Supplier) */ public abstract > M toMap(ShortFunction keyExtractor, ShortFunction valueMapper, Supplier mapFactory); /** * * @param keyExtractor * @param valueMapper * @param mergeFunction * @return * @see Collectors#toMap(Function, Function, BinaryOperator) */ public abstract Map toMap(ShortFunction keyExtractor, ShortFunction valueMapper, BinaryOperator mergeFunction); /** * * @param keyExtractor * @param valueMapper * @param mergeFunction * @param mapFactory * @return * @see Collectors#toMap(Function, Function, BinaryOperator, Supplier) */ public abstract > M toMap(ShortFunction keyExtractor, ShortFunction valueMapper, BinaryOperator mergeFunction, Supplier mapFactory); /** * * @param classifier * @param downstream * @return * @see Collectors#groupingBy(Function, Collector) */ public abstract Map toMap(final ShortFunction classifier, final Collector downstream); /** * * @param classifier * @param downstream * @param mapFactory * @return * @see Collectors#groupingBy(Function, Collector, Supplier) */ public abstract > M toMap(final ShortFunction classifier, final Collector downstream, final Supplier mapFactory); /** * * @param keyExtractor * @return * @see Collectors#toMultimap(Function) */ public abstract Multimap> toMultimap(ShortFunction keyExtractor); /** * * @param keyExtractor * @param mapFactory * @return * @see Collectors#toMultimap(Function, Supplier) */ public abstract > Multimap toMultimap(ShortFunction keyExtractor, Supplier> mapFactory); /** * * @param keyExtractor * @param valueMapper * @return * @see Collectors#toMultimap(Function, Function) */ public abstract Multimap> toMultimap(ShortFunction keyExtractor, ShortFunction valueMapper); /** * * @param keyExtractor * @param valueMapper * @param mapFactory * @return * @see Collectors#toMap(Function, Function, BinaryOperator, Supplier) */ public abstract > Multimap toMultimap(ShortFunction keyExtractor, ShortFunction valueMapper, Supplier> mapFactory); public abstract ShortMatrix toMatrix(); /** * 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
     *     int result = identity;
     *     for (int element : this stream)
     *         result = accumulator.applyAsShort(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 x}, * {@code accumulator.apply(identity, x)} is equal to {@code x}. * The {@code accumulator} function must be an * associative function. * *

This is a terminal * operation. * * @apiNote Sum, min, max, and average are all special cases of reduction. * Summing a stream of numbers can be expressed as: * *

{@code
     *     int sum = integers.reduce(0, (a, b) -> a+b);
     * }
* * or more compactly: * *
{@code
     *     int sum = integers.reduce(0, Shorteger::sum);
     * }
* *

While this may seem a more roundabout way to perform an aggregation * compared to simply mutating a running total in a loop, reduction * operations parallelize more gracefully, without needing additional * synchronization and with greatly reduced risk of data races. * * @param identity the identity value for the accumulating function * @param op an associative, * non-interfering, * stateless * function for combining two values * @return the result of the reduction * @see #sum() * @see #min() * @see #max() * @see #average() */ public abstract short reduce(short identity, ShortBinaryOperator op); /** * Performs a reduction on the * elements of this stream, using an * associative accumulation * function, and returns an {@code OptionalShort} describing the reduced value, * if any. This is equivalent to: *

{@code
     *     boolean foundAny = false;
     *     int result = null;
     *     for (int element : this stream) {
     *         if (!foundAny) {
     *             foundAny = true;
     *             result = element;
     *         }
     *         else
     *             result = accumulator.applyAsShort(result, element);
     *     }
     *     return foundAny ? OptionalShort.of(result) : OptionalShort.empty();
     * }
* * but is not constrained to execute sequentially. * *

The {@code accumulator} function must be an * associative function. * *

This is a terminal * operation. * * @param op an associative, * non-interfering, * stateless * function for combining two values * @return the result of the reduction * @see #reduce(int, ShortBinaryOperator) */ public abstract OptionalShort reduce(ShortBinaryOperator op); /** * 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 (int element : this stream)
     *         accumulator.accept(result, element);
     *     return result;
     * }
* *

Like {@link #reduce(int, ShortBinaryOperator)}, {@code collect} operations * can be parallelized without requiring additional synchronization. * *

This is a terminal * operation. * * @param type of the result * @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 * @see Stream#collect(Supplier, BiConsumer, BiConsumer) */ public abstract R collect(Supplier supplier, ObjShortConsumer accumulator, BiConsumer combiner); /** * * @param supplier * @param accumulator * @return */ public abstract R collect(Supplier supplier, ObjShortConsumer accumulator); /** * Head and tail should be used by pair. If only one is called, should use first() or skip(1) instead. * Don't call any other methods with this stream after head() and tail() are called. * * @return */ public abstract OptionalShort head(); /** * Head and tail should be used by pair. If only one is called, should use first() or skip(1) instead. * Don't call any other methods with this stream after head() and tail() are called. * * @return */ public abstract ShortStream tail(); /** * Head2 and tail2 should be used by pair. * Don't call any other methods with this stream after head2() and tail2() are called. * * @return */ public abstract ShortStream head2(); /** * Head2 and tail2 should be used by pair. * Don't call any other methods with this stream after head2() and tail2() are called. * * @return */ public abstract OptionalShort tail2(); public abstract Pair headAndTail(); public abstract Pair headAndTail2(); /** * Returns an {@code OptionalShort} describing the minimum element of this * stream, or an empty optional if this stream is empty. This is a special * case of a reduction * and is equivalent to: *

{@code
     *     return reduce(Shorteger::min);
     * }
* *

This is a terminal operation. * * @return an {@code OptionalShort} containing the minimum element of this * stream, or an empty {@code OptionalShort} if the stream is empty */ public abstract OptionalShort min(); /** * Returns an {@code OptionalShort} describing the maximum element of this * stream, or an empty optional if this stream is empty. This is a special * case of a reduction * and is equivalent to: *

{@code
     *     return reduce(Shorteger::max);
     * }
* *

This is a terminal * operation. * * @return an {@code OptionalShort} containing the maximum element of this * stream, or an empty {@code OptionalShort} if the stream is empty */ public abstract OptionalShort max(); /** * * @param k * @return OptionalByte.empty() if there is no element or count less than k, otherwise the kth largest element. */ public abstract OptionalShort kthLargest(int k); public abstract long sum(); public abstract OptionalDouble average(); public abstract ShortSummaryStatistics summarize(); public abstract Pair>> summarize2(); /** * * @param b * @param nextSelector first parameter is selected if Nth.FIRST is returned, otherwise the second parameter is selected. * @return */ public abstract ShortStream merge(final ShortStream b, final ShortBiFunction nextSelector); public abstract ShortStream zipWith(ShortStream b, ShortBiFunction zipFunction); public abstract ShortStream zipWith(ShortStream b, ShortStream c, ShortTriFunction zipFunction); public abstract ShortStream zipWith(ShortStream b, short valueForNoneA, short valueForNoneB, ShortBiFunction zipFunction); public abstract ShortStream zipWith(ShortStream b, ShortStream c, short valueForNoneA, short valueForNoneB, short valueForNoneC, ShortTriFunction zipFunction); /** * Returns a {@code LongStream} consisting of the elements of this stream, * converted to {@code long}. * *

This is an intermediate * operation. * * @return a {@code LongStream} consisting of the elements of this stream, * converted to {@code long} */ public abstract IntStream asIntStream(); /** * Returns a {@code Stream} consisting of the elements of this stream, * each boxed to an {@code Shorteger}. * *

This is an intermediate * operation. * * @return a {@code Stream} consistent of the elements of this stream, * each boxed to an {@code Shorteger} */ public abstract Stream boxed(); @Override public ShortIterator iterator() { return exIterator(); } abstract ExShortIterator exIterator(); public SS __(Function transfer) { return transfer.apply(this); } public static ShortStream empty() { return EMPTY; } @SafeVarargs public static ShortStream of(final short... a) { return N.isNullOrEmpty(a) ? empty() : new ArrayShortStream(a); } public static ShortStream of(final short[] a, final int startIndex, final int endIndex) { return N.isNullOrEmpty(a) && (startIndex == 0 && endIndex == 0) ? empty() : new ArrayShortStream(a, startIndex, endIndex); } public static ShortStream of(final short[][] a) { return N.isNullOrEmpty(a) ? empty() : Stream.of(a).flatMapToShort(new Function() { @Override public ShortStream apply(short[] t) { return ShortStream.of(t); } }); } public static ShortStream of(final short[][][] a) { return N.isNullOrEmpty(a) ? empty() : Stream.of(a).flatMapToShort(new Function() { @Override public ShortStream apply(short[][] t) { return ShortStream.of(t); } }); } public static ShortStream of(final ShortIterator iterator) { return iterator == null ? empty() : new IteratorShortStream(iterator); } public static ShortStream range(final short startInclusive, final short endExclusive) { if (startInclusive >= endExclusive) { return empty(); } return new IteratorShortStream(new ExShortIterator() { private short next = startInclusive; private int cnt = endExclusive * 1 - startInclusive; @Override public boolean hasNext() { return cnt > 0; } @Override public short nextShort() { if (cnt-- <= 0) { throw new NoSuchElementException(); } return next++; } @Override public void skip(long n) { cnt = n >= cnt ? 0 : cnt - (int) n; next += n; } @Override public long count() { return cnt; } @Override public short[] toArray() { final short[] result = new short[cnt]; for (int i = 0; i < cnt; i++) { result[i] = next++; } cnt = 0; return result; } }); } public static ShortStream range(final short startInclusive, final short endExclusive, final short by) { if (by == 0) { throw new IllegalArgumentException("'by' can't be zero"); } if (endExclusive == startInclusive || endExclusive > startInclusive != by > 0) { return empty(); } return new IteratorShortStream(new ExShortIterator() { private short next = startInclusive; private int cnt = (endExclusive * 1 - startInclusive) / by + ((endExclusive * 1 - startInclusive) % by == 0 ? 0 : 1); @Override public boolean hasNext() { return cnt > 0; } @Override public short nextShort() { if (cnt-- <= 0) { throw new NoSuchElementException(); } short result = next; next += by; return result; } @Override public void skip(long n) { cnt = n >= cnt ? 0 : cnt - (int) n; next += n * by; } @Override public long count() { return cnt; } @Override public short[] toArray() { final short[] result = new short[cnt]; for (int i = 0; i < cnt; i++, next += by) { result[i] = next; } cnt = 0; return result; } }); } public static ShortStream rangeClosed(final short startInclusive, final short endInclusive) { if (startInclusive > endInclusive) { return empty(); } else if (startInclusive == endInclusive) { return of(startInclusive); } return new IteratorShortStream(new ExShortIterator() { private short next = startInclusive; private int cnt = endInclusive * 1 - startInclusive + 1; @Override public boolean hasNext() { return cnt > 0; } @Override public short nextShort() { if (cnt-- <= 0) { throw new NoSuchElementException(); } return next++; } @Override public void skip(long n) { cnt = n >= cnt ? 0 : cnt - (int) n; next += n; } @Override public long count() { return cnt; } @Override public short[] toArray() { final short[] result = new short[cnt]; for (int i = 0; i < cnt; i++) { result[i] = next++; } cnt = 0; return result; } }); } public static ShortStream rangeClosed(final short startInclusive, final short endInclusive, final short by) { if (by == 0) { throw new IllegalArgumentException("'by' can't be zero"); } if (endInclusive == startInclusive) { return of(startInclusive); } else if (endInclusive > startInclusive != by > 0) { return empty(); } return new IteratorShortStream(new ExShortIterator() { private short next = startInclusive; private int cnt = (endInclusive * 1 - startInclusive) / by + 1; @Override public boolean hasNext() { return cnt > 0; } @Override public short nextShort() { if (cnt-- <= 0) { throw new NoSuchElementException(); } short result = next; next += by; return result; } @Override public void skip(long n) { cnt = n >= cnt ? 0 : cnt - (int) n; next += n * by; } @Override public long count() { return cnt; } @Override public short[] toArray() { final short[] result = new short[cnt]; for (int i = 0; i < cnt; i++, next += by) { result[i] = next; } cnt = 0; return result; } }); } public static ShortStream repeat(final short element, final long n) { if (n < 0) { throw new IllegalArgumentException("'n' can't be negative: " + n); } else if (n == 0) { return empty(); } return new IteratorShortStream(new ExShortIterator() { private long cnt = n; @Override public boolean hasNext() { return cnt > 0; } @Override public short nextShort() { if (cnt-- <= 0) { throw new NoSuchElementException(); } return element; } @Override public void skip(long n) { cnt = n >= cnt ? 0 : cnt - (int) n; } @Override public long count() { return cnt; } @Override public short[] toArray() { final short[] result = new short[(int) cnt]; for (int i = 0; i < cnt; i++) { result[i] = element; } cnt = 0; return result; } }); } public static ShortStream random() { return generate(new ShortSupplier() { @Override public short getAsShort() { return (short) RAND.nextInt(); } }); } public static ShortStream iterate(final Supplier hasNext, final ShortSupplier next) { N.requireNonNull(hasNext); N.requireNonNull(next); return new IteratorShortStream(new ExShortIterator() { private boolean hasNextVal = false; @Override public boolean hasNext() { if (hasNextVal == false) { hasNextVal = hasNext.get().booleanValue(); } return hasNextVal; } @Override public short nextShort() { if (hasNextVal == false && hasNext() == false) { throw new NoSuchElementException(); } hasNextVal = false; return next.getAsShort(); } }); } public static ShortStream iterate(final short seed, final Supplier hasNext, final ShortUnaryOperator f) { N.requireNonNull(hasNext); N.requireNonNull(f); return new IteratorShortStream(new ExShortIterator() { private short t = 0; private boolean isFirst = true; private boolean hasNextVal = false; @Override public boolean hasNext() { if (hasNextVal == false) { hasNextVal = hasNext.get().booleanValue(); } return hasNextVal; } @Override public short nextShort() { if (hasNextVal == false && hasNext() == false) { throw new NoSuchElementException(); } hasNextVal = false; if (isFirst) { isFirst = false; t = seed; } else { t = f.applyAsShort(t); } return t; } }); } /** * * @param seed * @param hasNext test if has next by hasNext.test(seed) for first time and hasNext.test(f.apply(previous)) for remaining. * @param f * @return */ public static ShortStream iterate(final short seed, final ShortPredicate hasNext, final ShortUnaryOperator f) { N.requireNonNull(hasNext); N.requireNonNull(f); return new IteratorShortStream(new ExShortIterator() { private short t = 0; private short cur = 0; private boolean isFirst = true; private boolean hasMore = true; private boolean hasNextVal = false; @Override public boolean hasNext() { if (hasNextVal == false && hasMore) { if (isFirst) { isFirst = false; hasNextVal = hasNext.test(cur = seed); } else { hasNextVal = hasNext.test(cur = f.applyAsShort(t)); } if (hasNextVal == false) { hasMore = false; } } return hasNextVal; } @Override public short nextShort() { if (hasNextVal == false && hasNext() == false) { throw new NoSuchElementException(); } t = cur; hasNextVal = false; return t; } }); } public static ShortStream iterate(final short seed, final ShortUnaryOperator f) { N.requireNonNull(f); return new IteratorShortStream(new ExShortIterator() { private short t = 0; private boolean isFirst = true; @Override public boolean hasNext() { return true; } @Override public short nextShort() { if (isFirst) { isFirst = false; t = seed; } else { t = f.applyAsShort(t); } return t; } }); } public static ShortStream generate(final ShortSupplier s) { N.requireNonNull(s); return new IteratorShortStream(new ExShortIterator() { @Override public boolean hasNext() { return true; } @Override public short nextShort() { return s.getAsShort(); } }); } @SafeVarargs public static ShortStream concat(final short[]... a) { return N.isNullOrEmpty(a) ? empty() : new IteratorShortStream(new ExShortIterator() { private final Iterator iter = N.asList(a).iterator(); private ShortIterator cur; @Override public boolean hasNext() { while ((cur == null || cur.hasNext() == false) && iter.hasNext()) { cur = ExShortIterator.of(iter.next()); } return cur != null && cur.hasNext(); } @Override public short nextShort() { if ((cur == null || cur.hasNext() == false) && hasNext() == false) { throw new NoSuchElementException(); } return cur.nextShort(); } }); } @SafeVarargs public static ShortStream concat(final ShortIterator... a) { return N.isNullOrEmpty(a) ? empty() : new IteratorShortStream(new ExShortIterator() { private final Iterator iter = N.asList(a).iterator(); private ShortIterator cur; @Override public boolean hasNext() { while ((cur == null || cur.hasNext() == false) && iter.hasNext()) { cur = iter.next(); } return cur != null && cur.hasNext(); } @Override public short nextShort() { if ((cur == null || cur.hasNext() == false) && hasNext() == false) { throw new NoSuchElementException(); } return cur.nextShort(); } }); } @SafeVarargs public static ShortStream concat(final ShortStream... a) { return N.isNullOrEmpty(a) ? empty() : concat(N.asList(a)); } public static ShortStream concat(final Collection c) { return N.isNullOrEmpty(c) ? empty() : new IteratorShortStream(new ExShortIterator() { private final Iterator iter = c.iterator(); private ShortIterator cur; @Override public boolean hasNext() { while ((cur == null || cur.hasNext() == false) && iter.hasNext()) { cur = iter.next().exIterator(); } return cur != null && cur.hasNext(); } @Override public short nextShort() { if ((cur == null || cur.hasNext() == false) && hasNext() == false) { throw new NoSuchElementException(); } return cur.nextShort(); } }).onClose(newCloseHandler(c)); } /** * Zip together the "a" and "b" arrays until one of them runs out of values. * Each pair of values is combined into a single value using the supplied zipFunction function. * * @param a * @param b * @return */ public static ShortStream zip(final short[] a, final short[] b, final ShortBiFunction zipFunction) { return Stream.zip(a, b, zipFunction).mapToShort(ToShortFunction.UNBOX); } /** * Zip together the "a", "b" and "c" arrays until one of them runs out of values. * Each triple of values is combined into a single value using the supplied zipFunction function. * * @param a * @param b * @return */ public static ShortStream zip(final short[] a, final short[] b, final short[] c, final ShortTriFunction zipFunction) { return Stream.zip(a, b, c, zipFunction).mapToShort(ToShortFunction.UNBOX); } /** * Zip together the "a" and "b" iterators until one of them runs out of values. * Each pair of values is combined into a single value using the supplied zipFunction function. * * @param a * @param b * @return */ public static ShortStream zip(final ShortIterator a, final ShortIterator b, final ShortBiFunction zipFunction) { return Stream.zip(a, b, zipFunction).mapToShort(ToShortFunction.UNBOX); } /** * Zip together the "a", "b" and "c" iterators until one of them runs out of values. * Each triple of values is combined into a single value using the supplied zipFunction function. * * @param a * @param b * @return */ public static ShortStream zip(final ShortIterator a, final ShortIterator b, final ShortIterator c, final ShortTriFunction zipFunction) { return Stream.zip(a, b, c, zipFunction).mapToShort(ToShortFunction.UNBOX); } /** * Zip together the "a" and "b" streams until one of them runs out of values. * Each pair of values is combined into a single value using the supplied zipFunction function. * * @param a * @param b * @return */ public static ShortStream zip(final ShortStream a, final ShortStream b, final ShortBiFunction zipFunction) { return Stream.zip(a, b, zipFunction).mapToShort(ToShortFunction.UNBOX); } /** * Zip together the "a", "b" and "c" streams until one of them runs out of values. * Each triple of values is combined into a single value using the supplied zipFunction function. * * @param a * @param b * @return */ public static ShortStream zip(final ShortStream a, final ShortStream b, final ShortStream c, final ShortTriFunction zipFunction) { return Stream.zip(a, b, c, zipFunction).mapToShort(ToShortFunction.UNBOX); } /** * Zip together the iterators until one of them runs out of values. * Each array of values is combined into a single value using the supplied zipFunction function. * * @param c * @param zipFunction * @return */ public static ShortStream zip(final Collection c, final ShortNFunction zipFunction) { return Stream.zip(c, zipFunction).mapToShort(ToShortFunction.UNBOX); } /** * Zip together the "a" and "b" iterators until all of them runs out of values. * Each pair of values is combined into a single value using the supplied zipFunction function. * * @param a * @param b * @param valueForNoneA value to fill if "a" runs out of values first. * @param valueForNoneB value to fill if "b" runs out of values first. * @param zipFunction * @return */ public static ShortStream zip(final short[] a, final short[] b, final short valueForNoneA, final short valueForNoneB, final ShortBiFunction zipFunction) { return Stream.zip(a, b, valueForNoneA, valueForNoneB, zipFunction).mapToShort(ToShortFunction.UNBOX); } /** * Zip together the "a", "b" and "c" iterators until all of them runs out of values. * Each triple of values is combined into a single value using the supplied zipFunction function. * * @param a * @param b * @param c * @param valueForNoneA value to fill if "a" runs out of values. * @param valueForNoneB value to fill if "b" runs out of values. * @param valueForNoneC value to fill if "c" runs out of values. * @param zipFunction * @return */ public static ShortStream zip(final short[] a, final short[] b, final short[] c, final short valueForNoneA, final short valueForNoneB, final short valueForNoneC, final ShortTriFunction zipFunction) { return Stream.zip(a, b, c, valueForNoneA, valueForNoneB, valueForNoneC, zipFunction).mapToShort(ToShortFunction.UNBOX); } /** * Zip together the "a" and "b" iterators until all of them runs out of values. * Each pair of values is combined into a single value using the supplied zipFunction function. * * @param a * @param b * @param valueForNoneA value to fill if "a" runs out of values first. * @param valueForNoneB value to fill if "b" runs out of values first. * @param zipFunction * @return */ public static ShortStream zip(final ShortIterator a, final ShortIterator b, final short valueForNoneA, final short valueForNoneB, final ShortBiFunction zipFunction) { return Stream.zip(a, b, valueForNoneA, valueForNoneB, zipFunction).mapToShort(ToShortFunction.UNBOX); } /** * Zip together the "a", "b" and "c" iterators until all of them runs out of values. * Each triple of values is combined into a single value using the supplied zipFunction function. * * @param a * @param b * @param c * @param valueForNoneA value to fill if "a" runs out of values. * @param valueForNoneB value to fill if "b" runs out of values. * @param valueForNoneC value to fill if "c" runs out of values. * @param zipFunction * @return */ public static ShortStream zip(final ShortIterator a, final ShortIterator b, final ShortIterator c, final short valueForNoneA, final short valueForNoneB, final short valueForNoneC, final ShortTriFunction zipFunction) { return Stream.zip(a, b, c, valueForNoneA, valueForNoneB, valueForNoneC, zipFunction).mapToShort(ToShortFunction.UNBOX); } /** * Zip together the "a" and "b" iterators until all of them runs out of values. * Each pair of values is combined into a single value using the supplied zipFunction function. * * @param a * @param b * @param valueForNoneA value to fill if "a" runs out of values first. * @param valueForNoneB value to fill if "b" runs out of values first. * @param zipFunction * @return */ public static ShortStream zip(final ShortStream a, final ShortStream b, final short valueForNoneA, final short valueForNoneB, final ShortBiFunction zipFunction) { return Stream.zip(a, b, valueForNoneA, valueForNoneB, zipFunction).mapToShort(ToShortFunction.UNBOX); } /** * Zip together the "a", "b" and "c" iterators until all of them runs out of values. * Each triple of values is combined into a single value using the supplied zipFunction function. * * @param a * @param b * @param c * @param valueForNoneA value to fill if "a" runs out of values. * @param valueForNoneB value to fill if "b" runs out of values. * @param valueForNoneC value to fill if "c" runs out of values. * @param zipFunction * @return */ public static ShortStream zip(final ShortStream a, final ShortStream b, final ShortStream c, final short valueForNoneA, final short valueForNoneB, final short valueForNoneC, final ShortTriFunction zipFunction) { return Stream.zip(a, b, c, valueForNoneA, valueForNoneB, valueForNoneC, zipFunction).mapToShort(ToShortFunction.UNBOX); } /** * Zip together the iterators until all of them runs out of values. * Each array of values is combined into a single value using the supplied zipFunction function. * * @param c * @param valuesForNone value to fill for any iterator runs out of values. * @param zipFunction * @return */ public static ShortStream zip(final Collection c, final short[] valuesForNone, final ShortNFunction zipFunction) { return Stream.zip(c, valuesForNone, zipFunction).mapToShort(ToShortFunction.UNBOX); } /** * * @param a * @param b * @param nextSelector first parameter is selected if Nth.FIRST is returned, otherwise the second parameter is selected. * @return */ public static ShortStream merge(final short[] a, final short[] b, final ShortBiFunction nextSelector) { if (N.isNullOrEmpty(a)) { return of(b); } else if (N.isNullOrEmpty(b)) { return of(a); } return new IteratorShortStream(new ExShortIterator() { private final int lenA = a.length; private final int lenB = b.length; private int cursorA = 0; private int cursorB = 0; @Override public boolean hasNext() { return cursorA < lenA || cursorB < lenB; } @Override public short nextShort() { if (cursorA < lenA) { if (cursorB < lenB) { if (nextSelector.apply(a[cursorA], b[cursorB]) == Nth.FIRST) { return a[cursorA++]; } else { return b[cursorB++]; } } else { return a[cursorA++]; } } else if (cursorB < lenB) { return b[cursorB++]; } else { throw new NoSuchElementException(); } } }); } /** * * @param a * @param b * @param c * @param nextSelector first parameter is selected if Nth.FIRST is returned, otherwise the second parameter is selected. * @return */ public static ShortStream merge(final short[] a, final short[] b, final short[] c, final ShortBiFunction nextSelector) { return merge(merge(a, b, nextSelector).exIterator(), ShortStream.of(c).exIterator(), nextSelector); } /** * * @param a * @param b * @param nextSelector first parameter is selected if Nth.FIRST is returned, otherwise the second parameter is selected. * @return */ public static ShortStream merge(final ShortIterator a, final ShortIterator b, final ShortBiFunction nextSelector) { if (a.hasNext() == false) { return of(b); } else if (b.hasNext() == false) { return of(a); } return new IteratorShortStream(new ExShortIterator() { private short nextA = 0; private short nextB = 0; private boolean hasNextA = false; private boolean hasNextB = false; @Override public boolean hasNext() { return a.hasNext() || b.hasNext() || hasNextA || hasNextB; } @Override public short nextShort() { if (hasNextA) { if (b.hasNext()) { if (nextSelector.apply(nextA, (nextB = b.nextShort())) == Nth.FIRST) { hasNextA = false; hasNextB = true; return nextA; } else { return nextB; } } else { hasNextA = false; return nextA; } } else if (hasNextB) { if (a.hasNext()) { if (nextSelector.apply((nextA = a.nextShort()), nextB) == Nth.FIRST) { return nextA; } else { hasNextA = true; hasNextB = false; return nextB; } } else { hasNextB = false; return nextB; } } else if (a.hasNext()) { if (b.hasNext()) { if (nextSelector.apply((nextA = a.nextShort()), (nextB = b.nextShort())) == Nth.FIRST) { hasNextB = true; return nextA; } else { hasNextA = true; return nextB; } } else { return a.nextShort(); } } else if (b.hasNext()) { return b.nextShort(); } else { throw new NoSuchElementException(); } } }); } /** * * @param a * @param b * @param c * @param nextSelector first parameter is selected if Nth.FIRST is returned, otherwise the second parameter is selected. * @return */ public static ShortStream merge(final ShortIterator a, final ShortIterator b, final ShortIterator c, final ShortBiFunction nextSelector) { return merge(merge(a, b, nextSelector).exIterator(), c, nextSelector); } /** * * @param a * @param b * @param nextSelector first parameter is selected if Nth.FIRST is returned, otherwise the second parameter is selected. * @return */ public static ShortStream merge(final ShortStream a, final ShortStream b, final ShortBiFunction nextSelector) { return merge(a.exIterator(), b.exIterator(), nextSelector).onClose(newCloseHandler(N.asList(a, b))); } /** * * @param a * @param b * @param c * @param nextSelector first parameter is selected if Nth.FIRST is returned, otherwise the second parameter is selected. * @return */ public static ShortStream merge(final ShortStream a, final ShortStream b, final ShortStream c, final ShortBiFunction nextSelector) { return merge(N.asList(a, b, c), nextSelector); } /** * * @param c * @param nextSelector first parameter is selected if Nth.FIRST is returned, otherwise the second parameter is selected. * @return */ public static ShortStream merge(final Collection c, final ShortBiFunction nextSelector) { if (N.isNullOrEmpty(c)) { return empty(); } else if (c.size() == 1) { return c.iterator().next(); } else if (c.size() == 2) { final Iterator iter = c.iterator(); return merge(iter.next(), iter.next(), nextSelector); } final Iterator iter = c.iterator(); ShortStream result = merge(iter.next().exIterator(), iter.next().exIterator(), nextSelector); while (iter.hasNext()) { result = merge(result.exIterator(), iter.next().exIterator(), nextSelector); } return result.onClose(newCloseHandler(c)); } /** * * @param c * @param nextSelector first parameter is selected if Nth.FIRST is returned, otherwise the second parameter is selected. * @return */ public static ShortStream parallelMerge(final Collection c, final ShortBiFunction nextSelector) { return parallelMerge(c, nextSelector, DEFAULT_MAX_THREAD_NUM); } /** * * @param c * @param nextSelector first parameter is selected if Nth.FIRST is returned, otherwise the second parameter is selected. * @param maxThreadNum * @return */ public static ShortStream parallelMerge(final Collection c, final ShortBiFunction nextSelector, final int maxThreadNum) { if (maxThreadNum < 1 || maxThreadNum > MAX_THREAD_NUM_PER_OPERATION) { throw new IllegalArgumentException("'maxThreadNum' must not less than 1 or exceeded: " + MAX_THREAD_NUM_PER_OPERATION); } if (N.isNullOrEmpty(c)) { return empty(); } else if (c.size() == 1) { return c.iterator().next(); } else if (c.size() == 2) { final Iterator iter = c.iterator(); return merge(iter.next(), iter.next(), nextSelector); } else if (maxThreadNum <= 1) { return merge(c, nextSelector); } final Queue queue = N.newLinkedList(); for (ShortStream e : c) { queue.add(e.exIterator()); } final Holder eHolder = new Holder<>(); final MutableInt cnt = MutableInt.of(c.size()); final List> futureList = new ArrayList<>(c.size() - 1); for (int i = 0, n = N.min(maxThreadNum, c.size() / 2 + 1); i < n; i++) { futureList.add(asyncExecutor.execute(new Runnable() { @Override public void run() { ShortIterator a = null; ShortIterator b = null; ShortIterator c = null; try { while (eHolder.value() == null) { synchronized (queue) { if (cnt.intValue() > 2 && queue.size() > 1) { a = queue.poll(); b = queue.poll(); cnt.decrement(); } else { break; } } c = ExShortIterator.of(merge(a, b, nextSelector).toArray()); synchronized (queue) { queue.offer(c); } } } catch (Throwable e) { setError(eHolder, e); } } })); } complete(futureList, eHolder); // Should never happen. if (queue.size() != 2) { throw new AbacusException("Unknown error happened."); } return merge(queue.poll(), queue.poll(), nextSelector).onClose(newCloseHandler(c)); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy