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

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

Go to download

A general programming library in Java/Android. It's easy to learn and simple to use with concise and powerful APIs.

There is a newer version: 5.2.4
Show newest version
/*
 * Copyright (C) 2016, 2017, 2018, 2019 HaiYang Li
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.landawn.abacus.util.stream;

import java.nio.ShortBuffer;
import java.security.SecureRandom;
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.Random;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.BinaryOperator;
import java.util.function.BooleanSupplier;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;

import com.landawn.abacus.annotation.Beta;
import com.landawn.abacus.annotation.IntermediateOp;
import com.landawn.abacus.annotation.LazyEvaluation;
import com.landawn.abacus.annotation.ParallelSupported;
import com.landawn.abacus.annotation.SequentialOnly;
import com.landawn.abacus.annotation.TerminalOp;
import com.landawn.abacus.util.Array;
import com.landawn.abacus.util.AsyncExecutor;
import com.landawn.abacus.util.ClassUtil;
import com.landawn.abacus.util.ContinuableFuture;
import com.landawn.abacus.util.Fn.FnS;
import com.landawn.abacus.util.Holder;
import com.landawn.abacus.util.IndexedShort;
import com.landawn.abacus.util.MergeResult;
import com.landawn.abacus.util.MutableInt;
import com.landawn.abacus.util.N;
import com.landawn.abacus.util.Pair;
import com.landawn.abacus.util.Percentage;
import com.landawn.abacus.util.RateLimiter;
import com.landawn.abacus.util.ShortIterator;
import com.landawn.abacus.util.ShortList;
import com.landawn.abacus.util.ShortSummaryStatistics;
import com.landawn.abacus.util.Throwables;
import com.landawn.abacus.util.u.Optional;
import com.landawn.abacus.util.u.OptionalDouble;
import com.landawn.abacus.util.u.OptionalShort;
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.ShortTernaryOperator;
import com.landawn.abacus.util.function.ShortToIntFunction;
import com.landawn.abacus.util.function.ShortTriPredicate;
import com.landawn.abacus.util.function.ShortUnaryOperator;
import com.landawn.abacus.util.function.ToShortFunction;

/**
 * The Stream will be automatically closed after execution(A terminal method is executed/triggered).
 *
 * @see BaseStream
 * @see Stream
 */
@com.landawn.abacus.annotation.Immutable
@LazyEvaluation
public abstract class ShortStream
        extends StreamBase {

    static final Random RAND = new SecureRandom();

    ShortStream(final boolean sorted, final Collection closeHandlers) {
        super(sorted, null, closeHandlers);
    }

    @Override
    public ShortStream rateLimited(final RateLimiter rateLimiter) {
        checkArgNotNull(rateLimiter, "rateLimiter");

        final ShortConsumer action = it -> rateLimiter.acquire();

        if (isParallel()) {
            return sequential().onEach(action).parallel(maxThreadNum(), executorNumForVirtualThread(), splitor(), asyncExecutor(), cancelUncompletedThreads());
        } else {
            return onEach(action);
        }
    }

    @Override
    public ShortStream skipUntil(final ShortPredicate predicate) {
        assertNotClosed();

        return dropWhile(t -> !predicate.test(t));
    }

    @ParallelSupported
    @IntermediateOp
    public abstract ShortStream map(ShortUnaryOperator mapper);

    @ParallelSupported
    @IntermediateOp
    public abstract IntStream mapToInt(ShortToIntFunction mapper);

    @ParallelSupported
    @IntermediateOp
    public abstract  Stream mapToObj(ShortFunction mapper);

    @ParallelSupported
    @IntermediateOp
    public abstract ShortStream flatMap(ShortFunction mapper);

    // public abstract ShortStream flatmap(ShortFunction mapper);

    @ParallelSupported
    @IntermediateOp
    public abstract ShortStream flatmap(ShortFunction mapper); //NOSONAR

    @ParallelSupported
    @IntermediateOp
    public abstract IntStream flatMapToInt(ShortFunction mapper);

    @ParallelSupported
    @IntermediateOp
    public abstract  Stream flatMapToObj(ShortFunction> mapper);

    @ParallelSupported
    @IntermediateOp
    public abstract  Stream flatmapToObj(ShortFunction> mapper); //NOSONAR

    @ParallelSupported
    @IntermediateOp
    public abstract  Stream flattMapToObj(ShortFunction mapper);

    /**
     * Note: copied from StreamEx: https://github.com/amaembo/streamex
     *
     * @param 
     * @param mapper
     * @return
     */
    @Beta
    @ParallelSupported
    @IntermediateOp
    public abstract ShortStream mapPartial(ShortFunction mapper);

    /**
     * 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. * This is a quasi-intermediate * partial reduction operation. * * @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 * @see #collapse(ShortBiPredicate, ShortBinaryOperator) * @see Stream#rangeMap(BiPredicate, BiFunction) */ @SequentialOnly @IntermediateOp public abstract ShortStream rangeMap(final ShortBiPredicate sameRange, final ShortBinaryOperator mapper); /** * 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. * This is a quasi-intermediate * partial reduction operation. * * @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 * @see Stream#rangeMap(BiPredicate, BiFunction) */ @SequentialOnly @IntermediateOp public abstract Stream rangeMapToObj(final ShortBiPredicate sameRange, final ShortBiFunction mapper); /** * Merge series of adjacent elements which satisfy the given predicate using * the merger function and return a new stream. * *
* This method only runs sequentially, even in parallel stream. * * @param collapsible * @return */ @SequentialOnly @IntermediateOp public abstract Stream collapse(final ShortBiPredicate collapsible); @SequentialOnly @IntermediateOp public abstract ShortStream collapse(final ShortBiPredicate collapsible, final ShortBinaryOperator mergeFunction); /** * * @param collapsible test the current element with the first element and previous element in the series. The first parameter is the first element of this series, the second parameter is the previous element and the third parameter is the current element. * @param mergeFunction * @return */ @SequentialOnly @IntermediateOp public abstract ShortStream collapse(final ShortTriPredicate collapsible, final ShortBinaryOperator mergeFunction); /** * Returns a {@code Stream} produced by iterative application of a accumulation function * to an initial element {@code init} and next element of the current stream. * Produces a {@code Stream} consisting of {@code init}, {@code acc(init, value1)}, * {@code acc(acc(init, value1), value2)}, etc. * *

This is an intermediate operation. * *

Example: *

     * accumulator: (a, b) -> a + b
     * stream: [1, 2, 3, 4, 5]
     * result: [1, 3, 6, 10, 15]
     * 
* *
* This method only runs sequentially, even in parallel stream. * * @param accumulator the accumulation function * @return */ @SequentialOnly @IntermediateOp public abstract ShortStream scan(final ShortBinaryOperator accumulator); /** * Returns a {@code Stream} produced by iterative application of a accumulation function * to an initial element {@code init} and next element of the current stream. * Produces a {@code Stream} consisting of {@code init}, {@code acc(init, value1)}, * {@code acc(acc(init, value1), value2)}, etc. * *

This is an intermediate operation. * *

Example: *

     * init:10
     * accumulator: (a, b) -> a + b
     * stream: [1, 2, 3, 4, 5]
     * result: [11, 13, 16, 20, 25]
     * 
* *
* This method only runs sequentially, even in parallel stream. * * @param init 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 */ @SequentialOnly @IntermediateOp public abstract ShortStream scan(final short init, final ShortBinaryOperator accumulator); /** * * @param init * @param accumulator * @param initIncluded * @return */ @SequentialOnly @IntermediateOp public abstract ShortStream scan(final short init, final ShortBinaryOperator accumulator, final boolean initIncluded); @SequentialOnly @IntermediateOp public abstract ShortStream prepend(final short... a); @SequentialOnly @IntermediateOp public abstract ShortStream append(final short... a); @SequentialOnly @IntermediateOp public abstract ShortStream appendIfEmpty(final short... a); /** *
* This method only runs sequentially, even in parallel stream. * * @param n * @return */ @SequentialOnly @IntermediateOp public abstract ShortStream top(int n); /** *
* This method only runs sequentially, even in parallel stream. * * @param n * @return */ @SequentialOnly @IntermediateOp public abstract ShortStream top(final int n, Comparator comparator); @SequentialOnly @TerminalOp public abstract ShortList toShortList(); /** * * @param keyMapper * @param valueMapper * @return * @see Collectors#toMap(Throwables.Function, Throwables.Function) */ @ParallelSupported @TerminalOp public abstract Map toMap(Throwables.ShortFunction keyMapper, Throwables.ShortFunction valueMapper) throws E, E2; /** * * @param keyMapper * @param valueMapper * @param mapFactory * @return * @see Collectors#toMap(Throwables.Function, Throwables.Function, Supplier) */ @ParallelSupported @TerminalOp public abstract , E extends Exception, E2 extends Exception> M toMap(Throwables.ShortFunction keyMapper, Throwables.ShortFunction valueMapper, Supplier mapFactory) throws E, E2; /** * * @param keyMapper * @param valueMapper * @param mergeFunction * @return * @see Collectors#toMap(Throwables.Function, Throwables.Function, BinaryOperator) */ @ParallelSupported @TerminalOp public abstract Map toMap(Throwables.ShortFunction keyMapper, Throwables.ShortFunction valueMapper, BinaryOperator mergeFunction) throws E, E2; /** * * @param keyMapper * @param valueMapper * @param mergeFunction * @param mapFactory * @return * @see Collectors#toMap(Throwables.Function, Throwables.Function, BinaryOperator, Supplier) */ @ParallelSupported @TerminalOp public abstract , E extends Exception, E2 extends Exception> M toMap(Throwables.ShortFunction keyMapper, Throwables.ShortFunction valueMapper, BinaryOperator mergeFunction, Supplier mapFactory) throws E, E2; /** * * @param keyMapper * @param downstream * @return * @see Collectors#groupingBy(Throwables.Function, Collector) */ @ParallelSupported @TerminalOp public abstract Map groupTo(Throwables.ShortFunction keyMapper, final Collector downstream) throws E; /** * * @param keyMapper * @param downstream * @param mapFactory * @return * @see Collectors#groupingBy(Throwables.Function, Collector, Supplier) */ @ParallelSupported @TerminalOp public abstract , E extends Exception> M groupTo(Throwables.ShortFunction keyMapper, final Collector downstream, final Supplier mapFactory) throws E; @ParallelSupported @TerminalOp public abstract short reduce(short identity, ShortBinaryOperator op); @ParallelSupported @TerminalOp public abstract OptionalShort reduce(ShortBinaryOperator op); /** * * @param * @param supplier * @param accumulator * @param combiner * @return * @see Stream#collect(Supplier, BiConsumer, BiConsumer) */ @ParallelSupported @TerminalOp public abstract R collect(Supplier supplier, ObjShortConsumer accumulator, BiConsumer combiner); /** * Only call this method when the returned type {@code R} is one types: {@code Collection/Map/StringBuilder/Multiset/LongMultiset/Multimap/BooleanList/IntList/.../DoubleList}. * Otherwise, please call {@link #collect(Supplier, ObjShortConsumer, BiConsumer)}. * * @param supplier * @param accumulator * @return * @see #collect(Supplier, ObjShortConsumer, BiConsumer) * @see Stream#collect(Supplier, BiConsumer) * @see Stream#collect(Supplier, BiConsumer, BiConsumer) */ @ParallelSupported @TerminalOp public abstract R collect(Supplier supplier, ObjShortConsumer accumulator); @ParallelSupported @TerminalOp public abstract void forEach(final Throwables.ShortConsumer action) throws E; @ParallelSupported @TerminalOp public abstract void forEachIndexed(Throwables.IndexedShortConsumer action) throws E; @ParallelSupported @TerminalOp public abstract boolean anyMatch(final Throwables.ShortPredicate predicate) throws E; @ParallelSupported @TerminalOp public abstract boolean allMatch(final Throwables.ShortPredicate predicate) throws E; @ParallelSupported @TerminalOp public abstract boolean noneMatch(final Throwables.ShortPredicate predicate) throws E; @ParallelSupported @TerminalOp public abstract OptionalShort findFirst(final Throwables.ShortPredicate predicate) throws E; /** * Returns the first element matched by {@code predicateForFirst} if found or the first element if this stream is not empty * Otherwise an empty {@code OptionalShort} will be returned. * * @param * @param predicateForFirst * @return * @throws E */ @ParallelSupported @TerminalOp public abstract OptionalShort findFirstOrAny(Throwables.ShortPredicate predicateForFirst) throws E; /** * Returns the first element matched by {@code predicateForFirst} if found or the last element if this stream is not empty * Otherwise an empty {@code OptionalShort} will be returned. * * @param * @param predicateForFirst * @return * @throws E */ @ParallelSupported @TerminalOp public abstract OptionalShort findFirstOrLast(Throwables.ShortPredicate predicateForFirst) throws E; /** * Consider using: {@code stream.reversed().findFirst(predicate)} for better performance if possible. * * @param * @param predicate * @return * @throws E */ @ParallelSupported @TerminalOp public abstract OptionalShort findLast(final Throwables.ShortPredicate predicate) throws E; @ParallelSupported @TerminalOp public abstract OptionalShort findAny(final Throwables.ShortPredicate predicate) throws E; @SequentialOnly @TerminalOp public abstract OptionalShort min(); @SequentialOnly @TerminalOp public abstract OptionalShort max(); /** * * @param k * @return OptionalByte.empty() if there is no element or count less than k, otherwise the kth largest element. */ @SequentialOnly @TerminalOp public abstract OptionalShort kthLargest(int k); @SequentialOnly @TerminalOp public abstract long sum(); @SequentialOnly @TerminalOp public abstract OptionalDouble average(); @SequentialOnly @TerminalOp public abstract ShortSummaryStatistics summarize(); @SequentialOnly @TerminalOp public abstract Pair>> summarizeAndPercentiles(); // /** // * // * @param b // * @param nextSelector first parameter is selected if Nth.FIRST is returned, otherwise the second parameter is selected. // * @return // * @deprecated replaced by {@code mergeWith(ShortStream, ShortBiFunction)} // * @see #mergeWith(ShortStream, ShortBiFunction) // */ // @SequentialOnly // @IntermediateOp // @Deprecated // public ShortStream merge(final ShortStream b, final ShortBiFunction nextSelector) { // return mergeWith(b, nextSelector); // } /** * * @param b * @param nextSelector first parameter is selected if Nth.FIRST is returned, otherwise the second parameter is selected. * @return */ @SequentialOnly @IntermediateOp public abstract ShortStream mergeWith(final ShortStream b, final ShortBiFunction nextSelector); @ParallelSupported @IntermediateOp public abstract ShortStream zipWith(ShortStream b, ShortBinaryOperator zipFunction); @ParallelSupported @IntermediateOp public abstract ShortStream zipWith(ShortStream b, ShortStream c, ShortTernaryOperator zipFunction); @ParallelSupported @IntermediateOp public abstract ShortStream zipWith(ShortStream b, short valueForNoneA, short valueForNoneB, ShortBinaryOperator zipFunction); @ParallelSupported @IntermediateOp public abstract ShortStream zipWith(ShortStream b, ShortStream c, short valueForNoneA, short valueForNoneB, short valueForNoneC, ShortTernaryOperator zipFunction); @SequentialOnly @IntermediateOp public abstract IntStream asIntStream(); @SequentialOnly @IntermediateOp public abstract Stream boxed(); /** * Remember to close this Stream after the iteration is done, if needed. * * @return */ @SequentialOnly @Override public ShortIterator iterator() { assertNotClosed(); if (!isEmptyCloseHandlers(closeHandlers) && logger.isWarnEnabled()) { logger.warn("### Remember to close " + ClassUtil.getSimpleClassName(getClass())); } return iteratorEx(); } abstract ShortIteratorEx iteratorEx(); public static ShortStream empty() { return new ArrayShortStream(N.EMPTY_SHORT_ARRAY, true, null); } public static ShortStream ofNullable(final Short e) { return e == null ? empty() : of(e); } @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 Stream.of(a).mapToShort(FnS.unbox()); } public static ShortStream of(final Short[] a, final int startIndex, final int endIndex) { return Stream.of(a, startIndex, endIndex).mapToShort(FnS.unbox()); } public static ShortStream of(final Collection c) { return Stream.of(c).mapToShort(FnS.unbox()); } public static ShortStream of(final ShortIterator iterator) { return iterator == null ? empty() : new IteratorShortStream(iterator); } public static ShortStream of(final ShortBuffer buf) { if (buf == null) { return empty(); } return IntStream.range(buf.position(), buf.limit()).mapToShort(buf::get); } /** * Lazy evaluation. *
* * This is equal to: {@code Stream.just(supplier).flatMapToShort(it -> it.get())}. * * @param * @param supplier * @return */ public static ShortStream defer(final Supplier supplier) { N.checkArgNotNull(supplier, "supplier"); return Stream.just(supplier).flatMapToShort(Supplier::get); } // /** // * Lazy evaluation. // *
// * // * This is equal to: {@code Stream.just(supplier).flatMapToShort(it -> it.get().stream())}. // * // * @param supplier // * @return // */ // @Beta // public static ShortStream from(final Supplier supplier) { // N.checkArgNotNull(supplier, "supplier"); // // return Stream.just(supplier).flatMapToShort(it -> it.get().stream()); // } private static final Function flatMapper = ShortStream::of; private static final Function flattMapper = ShortStream::flatten; public static ShortStream flatten(final short[][] a) { return N.isNullOrEmpty(a) ? empty() : Stream.of(a).flatMapToShort(flatMapper); } public static ShortStream flatten(final short[][] a, final boolean vertically) { if (N.isNullOrEmpty(a)) { return empty(); } else if (a.length == 1) { return of(a[0]); } else if (!vertically) { return Stream.of(a).flatMapToShort(flatMapper); } long n = 0; for (short[] e : a) { n += N.len(e); } if (n == 0) { return empty(); } final int rows = N.len(a); final long count = n; final ShortIterator iter = new ShortIteratorEx() { private int rowNum = 0; private int colNum = 0; private long cnt = 0; @Override public boolean hasNext() { return cnt < count; } @Override public short nextShort() { if (cnt++ >= count) { throw new NoSuchElementException(); } if (rowNum == rows) { rowNum = 0; colNum++; } while (a[rowNum] == null || colNum >= a[rowNum].length) { if (rowNum < rows - 1) { rowNum++; } else { rowNum = 0; colNum++; } } return a[rowNum++][colNum]; } }; return of(iter); } public static ShortStream flatten(final short[][] a, final short valueForNone, final boolean vertically) { if (N.isNullOrEmpty(a)) { return empty(); } else if (a.length == 1) { return of(a[0]); } long n = 0; int maxLen = 0; for (short[] e : a) { n += N.len(e); maxLen = N.max(maxLen, N.len(e)); } if (n == 0) { return empty(); } final int rows = N.len(a); final int cols = maxLen; final long count = (long) rows * cols; ShortIterator iter = null; if (vertically) { iter = new ShortIteratorEx() { private int rowNum = 0; private int colNum = 0; private long cnt = 0; @Override public boolean hasNext() { return cnt < count; } @Override public short nextShort() { if (cnt++ >= count) { throw new NoSuchElementException(); } if (rowNum == rows) { rowNum = 0; colNum++; } if (a[rowNum] == null || colNum >= a[rowNum].length) { rowNum++; return valueForNone; } else { return a[rowNum++][colNum]; } } }; } else { iter = new ShortIteratorEx() { private int rowNum = 0; private int colNum = 0; private long cnt = 0; @Override public boolean hasNext() { return cnt < count; } @Override public short nextShort() { if (cnt++ >= count) { throw new NoSuchElementException(); } if (colNum >= cols) { colNum = 0; rowNum++; } if (a[rowNum] == null || colNum >= a[rowNum].length) { colNum++; return valueForNone; } else { return a[rowNum][colNum++]; } } }; } return of(iter); } public static ShortStream flatten(final short[][][] a) { return N.isNullOrEmpty(a) ? empty() : Stream.of(a).flatMapToShort(flattMapper); } public static ShortStream range(final short startInclusive, final short endExclusive) { if (startInclusive >= endExclusive) { return empty(); } return new IteratorShortStream(new ShortIteratorEx() { 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 advance(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 ShortIteratorEx() { 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 advance(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 ShortIteratorEx() { 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 advance(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 ShortIteratorEx() { 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 advance(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) { N.checkArgNotNegative(n, "n"); if (n == 0) { return empty(); } else if (n < 10) { return of(Array.repeat(element, (int) n)); } return new IteratorShortStream(new ShortIteratorEx() { 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 advance(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() { final int bound = Short.MAX_VALUE - Short.MIN_VALUE + 1; return generate(() -> (short) (RAND.nextInt(bound) + Short.MIN_VALUE)); } public static ShortStream iterate(final BooleanSupplier hasNext, final ShortSupplier next) { N.checkArgNotNull(hasNext); N.checkArgNotNull(next); return new IteratorShortStream(new ShortIteratorEx() { private boolean hasNextVal = false; @Override public boolean hasNext() { if (!hasNextVal) { hasNextVal = hasNext.getAsBoolean(); } return hasNextVal; } @Override public short nextShort() { if (!hasNextVal && !hasNext()) { throw new NoSuchElementException(); } hasNextVal = false; return next.getAsShort(); } }); } public static ShortStream iterate(final short init, final BooleanSupplier hasNext, final ShortUnaryOperator f) { N.checkArgNotNull(hasNext); N.checkArgNotNull(f); return new IteratorShortStream(new ShortIteratorEx() { private short t = 0; private boolean isFirst = true; private boolean hasNextVal = false; @Override public boolean hasNext() { if (!hasNextVal) { hasNextVal = hasNext.getAsBoolean(); } return hasNextVal; } @Override public short nextShort() { if (!hasNextVal && !hasNext()) { throw new NoSuchElementException(); } hasNextVal = false; if (isFirst) { isFirst = false; t = init; } else { t = f.applyAsShort(t); } return t; } }); } /** * * @param init * @param hasNext test if has next by hasNext.test(init) for first time and hasNext.test(f.apply(previous)) for remaining. * @param f * @return */ public static ShortStream iterate(final short init, final ShortPredicate hasNext, final ShortUnaryOperator f) { N.checkArgNotNull(hasNext); N.checkArgNotNull(f); return new IteratorShortStream(new ShortIteratorEx() { 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 && hasMore) { if (isFirst) { isFirst = false; hasNextVal = hasNext.test(cur = init); } else { hasNextVal = hasNext.test(cur = f.applyAsShort(t)); } if (!hasNextVal) { hasMore = false; } } return hasNextVal; } @Override public short nextShort() { if (!hasNextVal && !hasNext()) { throw new NoSuchElementException(); } t = cur; hasNextVal = false; return t; } }); } public static ShortStream iterate(final short init, final ShortUnaryOperator f) { N.checkArgNotNull(f); return new IteratorShortStream(new ShortIteratorEx() { private short t = 0; private boolean isFirst = true; @Override public boolean hasNext() { return true; } @Override public short nextShort() { if (isFirst) { isFirst = false; t = init; } else { t = f.applyAsShort(t); } return t; } }); } public static ShortStream generate(final ShortSupplier s) { N.checkArgNotNull(s); return new IteratorShortStream(new ShortIteratorEx() { @Override public boolean hasNext() { return true; } @Override public short nextShort() { return s.getAsShort(); } }); } @SafeVarargs public static ShortStream concat(final short[]... a) { if (N.isNullOrEmpty(a)) { return empty(); } return concat(Arrays.asList(a)); } @SafeVarargs public static ShortStream concat(final ShortIterator... a) { if (N.isNullOrEmpty(a)) { return empty(); } return concatIterators(Array.asList(a)); } @SafeVarargs public static ShortStream concat(final ShortStream... a) { if (N.isNullOrEmpty(a)) { return empty(); } return concat(Array.asList(a)); } @Beta public static ShortStream concat(final List c) { if (N.isNullOrEmpty(c)) { return empty(); } return of(new ShortIteratorEx() { private final Iterator iter = c.iterator(); private short[] cur; private int cursor = 0; @Override public boolean hasNext() { while ((N.isNullOrEmpty(cur) || cursor >= cur.length) && iter.hasNext()) { cur = iter.next(); cursor = 0; } return cur != null && cursor < cur.length; } @Override public short nextShort() { if ((cur == null || cursor >= cur.length) && !hasNext()) { throw new NoSuchElementException(); } return cur[cursor++]; } }); } public static ShortStream concat(final Collection c) { return N.isNullOrEmpty(c) ? empty() : new IteratorShortStream(new ShortIteratorEx() { //NOSONAR private final Iterator iterators = c.iterator(); private ShortStream cur; private ShortIterator iter; @Override public boolean hasNext() { while ((iter == null || !iter.hasNext()) && iterators.hasNext()) { if (cur != null) { cur.close(); } cur = iterators.next(); iter = cur == null ? null : cur.iteratorEx(); } return iter != null && iter.hasNext(); } @Override public short nextShort() { if ((iter == null || !iter.hasNext()) && !hasNext()) { throw new NoSuchElementException(); } return iter.nextShort(); } }).onClose(newCloseHandler(c)); } @Beta public static ShortStream concatIterators(final Collection c) { if (N.isNullOrEmpty(c)) { return empty(); } return new IteratorShortStream(new ShortIteratorEx() { private final Iterator iter = c.iterator(); private ShortIterator cur; @Override public boolean hasNext() { while ((cur == null || !cur.hasNext()) && iter.hasNext()) { cur = iter.next(); } return cur != null && cur.hasNext(); } @Override public short nextShort() { if ((cur == null || !cur.hasNext()) && !hasNext()) { throw new NoSuchElementException(); } return cur.nextShort(); } }); } /** * 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 ShortBinaryOperator zipFunction) { if (N.isNullOrEmpty(a) || N.isNullOrEmpty(b)) { return empty(); } return new IteratorShortStream(new ShortIteratorEx() { private final int len = N.min(N.len(a), N.len(b)); private int cursor = 0; @Override public boolean hasNext() { return cursor < len; } @Override public short nextShort() { if (cursor >= len) { throw new NoSuchElementException(); } return zipFunction.applyAsShort(a[cursor], b[cursor++]); } }); } /** * 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 * @param c * @return */ public static ShortStream zip(final short[] a, final short[] b, final short[] c, final ShortTernaryOperator zipFunction) { if (N.isNullOrEmpty(a) || N.isNullOrEmpty(b) || N.isNullOrEmpty(c)) { return empty(); } return new IteratorShortStream(new ShortIteratorEx() { private final int len = N.min(N.len(a), N.len(b), N.len(c)); private int cursor = 0; @Override public boolean hasNext() { return cursor < len; } @Override public short nextShort() { if (cursor >= len) { throw new NoSuchElementException(); } return zipFunction.applyAsShort(a[cursor], b[cursor], c[cursor++]); } }); } /** * 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 ShortBinaryOperator zipFunction) { return new IteratorShortStream(new ShortIteratorEx() { private final ShortIterator iterA = a == null ? ShortIterator.empty() : a; private final ShortIterator iterB = b == null ? ShortIterator.empty() : b; @Override public boolean hasNext() { return iterA.hasNext() && iterB.hasNext(); } @Override public short nextShort() { return zipFunction.applyAsShort(iterA.nextShort(), iterB.nextShort()); } }); } /** * 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 ShortTernaryOperator zipFunction) { return new IteratorShortStream(new ShortIteratorEx() { private final ShortIterator iterA = a == null ? ShortIterator.empty() : a; private final ShortIterator iterB = b == null ? ShortIterator.empty() : b; private final ShortIterator iterC = c == null ? ShortIterator.empty() : c; @Override public boolean hasNext() { return iterA.hasNext() && iterB.hasNext() && iterC.hasNext(); } @Override public short nextShort() { return zipFunction.applyAsShort(iterA.nextShort(), iterB.nextShort(), iterC.nextShort()); } }); } /** * 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 ShortBinaryOperator zipFunction) { return zip(iterate(a), iterate(b), zipFunction).onClose(newCloseHandler(a, b)); } /** * 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 ShortTernaryOperator zipFunction) { return zip(iterate(a), iterate(b), iterate(c), zipFunction).onClose(newCloseHandler(Array.asList(a, b, c))); } /** * 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 ShortBinaryOperator zipFunction) { if (N.isNullOrEmpty(a) && N.isNullOrEmpty(b)) { return empty(); } return new IteratorShortStream(new ShortIteratorEx() { private final int aLen = N.len(a), bLen = N.len(b), len = N.max(aLen, bLen); private int cursor = 0; private short ret = 0; @Override public boolean hasNext() { return cursor < len; } @Override public short nextShort() { if (cursor >= len) { throw new NoSuchElementException(); } ret = zipFunction.applyAsShort(cursor < aLen ? a[cursor] : valueForNoneA, cursor < bLen ? b[cursor] : valueForNoneB); cursor++; return ret; } }); } /** * 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 ShortTernaryOperator zipFunction) { if (N.isNullOrEmpty(a) && N.isNullOrEmpty(b) && N.isNullOrEmpty(c)) { return empty(); } return new IteratorShortStream(new ShortIteratorEx() { private final int aLen = N.len(a), bLen = N.len(b), cLen = N.len(c), len = N.max(aLen, bLen, cLen); private int cursor = 0; private short ret = 0; @Override public boolean hasNext() { return cursor < len; } @Override public short nextShort() { if (cursor >= len) { throw new NoSuchElementException(); } ret = zipFunction.applyAsShort(cursor < aLen ? a[cursor] : valueForNoneA, cursor < bLen ? b[cursor] : valueForNoneB, cursor < cLen ? c[cursor] : valueForNoneC); cursor++; return ret; } }); } /** * 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 ShortBinaryOperator zipFunction) { return new IteratorShortStream(new ShortIteratorEx() { private final ShortIterator iterA = a == null ? ShortIterator.empty() : a; private final ShortIterator iterB = b == null ? ShortIterator.empty() : b; @Override public boolean hasNext() { return iterA.hasNext() || iterB.hasNext(); } @Override public short nextShort() { if (iterA.hasNext()) { return zipFunction.applyAsShort(iterA.nextShort(), iterB.hasNext() ? iterB.nextShort() : valueForNoneB); } else { return zipFunction.applyAsShort(valueForNoneA, iterB.nextShort()); } } }); } /** * 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 ShortTernaryOperator zipFunction) { return new IteratorShortStream(new ShortIteratorEx() { private final ShortIterator iterA = a == null ? ShortIterator.empty() : a; private final ShortIterator iterB = b == null ? ShortIterator.empty() : b; private final ShortIterator iterC = c == null ? ShortIterator.empty() : c; @Override public boolean hasNext() { return iterA.hasNext() || iterB.hasNext() || iterC.hasNext(); } @Override public short nextShort() { if (iterA.hasNext()) { return zipFunction.applyAsShort(iterA.nextShort(), iterB.hasNext() ? iterB.nextShort() : valueForNoneB, iterC.hasNext() ? iterC.nextShort() : valueForNoneC); } else if (iterB.hasNext()) { return zipFunction.applyAsShort(valueForNoneA, iterB.nextShort(), iterC.hasNext() ? iterC.nextShort() : valueForNoneC); } else { return zipFunction.applyAsShort(valueForNoneA, valueForNoneB, iterC.nextShort()); } } }); } /** * 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 ShortBinaryOperator zipFunction) { return zip(iterate(a), iterate(b), valueForNoneA, valueForNoneB, zipFunction).onClose(newCloseHandler(a, b)); } /** * 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 ShortTernaryOperator zipFunction) { return zip(iterate(a), iterate(b), iterate(c), valueForNoneA, valueForNoneB, valueForNoneC, zipFunction) .onClose(newCloseHandler(Array.asList(a, b, c))); } /** * 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 ShortIteratorEx() { 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]) == MergeResult.TAKE_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).iteratorEx(), ShortStream.of(c).iteratorEx(), 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) { return new IteratorShortStream(new ShortIteratorEx() { private final ShortIterator iterA = a == null ? ShortIterator.empty() : a; private final ShortIterator iterB = b == null ? ShortIterator.empty() : b; private short nextA = 0; private short nextB = 0; private boolean hasNextA = false; private boolean hasNextB = false; @Override public boolean hasNext() { return iterA.hasNext() || iterB.hasNext() || hasNextA || hasNextB; } @Override public short nextShort() { if (hasNextA) { if (iterB.hasNext()) { if (nextSelector.apply(nextA, (nextB = iterB.nextShort())) == MergeResult.TAKE_FIRST) { hasNextA = false; hasNextB = true; return nextA; } else { return nextB; } } else { hasNextA = false; return nextA; } } else if (hasNextB) { if (iterA.hasNext()) { if (nextSelector.apply((nextA = iterA.nextShort()), nextB) == MergeResult.TAKE_FIRST) { return nextA; } else { hasNextA = true; hasNextB = false; return nextB; } } else { hasNextB = false; return nextB; } } else if (iterA.hasNext()) { if (iterB.hasNext()) { if (nextSelector.apply((nextA = iterA.nextShort()), (nextB = iterB.nextShort())) == MergeResult.TAKE_FIRST) { hasNextB = true; return nextA; } else { hasNextA = true; return nextB; } } else { return iterA.nextShort(); } } else if (iterB.hasNext()) { return iterB.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).iteratorEx(), 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(iterate(a), iterate(b), nextSelector).onClose(newCloseHandler(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(merge(a, b, nextSelector), 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(), iter.next(), nextSelector); while (iter.hasNext()) { result = merge(result, iter.next(), nextSelector); } return result; } /** * All the elements from each input {@code Collection/Iterator/Stream} will be merged into two queues by multiple threads. * Then these two new queues will be merged into one {@code Iterator/Stream} by one thread. * So it's not totally lazy evaluation and may cause out of memory error if there are too many elements merged into the new queues. * Consider using {@code merge}, which is totally lazy evaluation. * * @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); } /** * All the elements from each input {@code Collection/Iterator/Stream} will be merged into two queues by multiple threads. * Then these two new queues will be merged into one {@code Iterator/Stream} by one thread. * So it's not totally lazy evaluation and may cause out of memory error if there are too many elements merged into the new queues. * Consider using {@code merge}, which is totally lazy evaluation. * * @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) { N.checkArgument(maxThreadNum > 0, "'maxThreadNum' must not less than 1"); if (maxThreadNum <= 1) { return merge(c, nextSelector); } else 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 (c.size() == 3) { final Iterator iter = c.iterator(); return merge(iter.next(), iter.next(), iter.next(), nextSelector); } final Supplier supplier = () -> { final Queue queue = N.newLinkedList(); queue.addAll(c); final Holder eHolder = new Holder<>(); final MutableInt cnt = MutableInt.of(c.size()); final List> futureList = new ArrayList<>(c.size() - 1); final int threadNum = N.min(maxThreadNum, c.size() / 2 + 1); AsyncExecutor asyncExecutorToUse = checkAsyncExecutor(DEFAULT_ASYNC_EXECUTOR, threadNum, 0); for (int i = 0; i < threadNum; i++) { asyncExecutorToUse = execute(asyncExecutorToUse, threadNum, 0, i, futureList, () -> { ShortStream a = null; ShortStream b = null; ShortStream c1 = 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; } } c1 = ShortStream.of(merge(a, b, nextSelector).toArray()); synchronized (queue) { queue.offer(c1); } } } catch (Throwable e) { setError(eHolder, e); } }); } completeAndShutdownTempExecutor(futureList, eHolder, c, asyncExecutorToUse); return merge(queue.poll(), queue.poll(), nextSelector); }; return Stream.just(supplier).flatMapToShort(Supplier::get); } public abstract static class ShortStreamEx extends ShortStream { private ShortStreamEx(boolean sorted, Collection closeHandlers) { //NOSONAR super(sorted, closeHandlers); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy