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

com.landawn.abacus.util.stream.FloatStream 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.FloatBuffer;
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.FloatIterator;
import com.landawn.abacus.util.FloatList;
import com.landawn.abacus.util.FloatSummaryStatistics;
import com.landawn.abacus.util.Fn.FnF;
import com.landawn.abacus.util.Holder;
import com.landawn.abacus.util.IndexedFloat;
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.Throwables;
import com.landawn.abacus.util.u.Optional;
import com.landawn.abacus.util.u.OptionalDouble;
import com.landawn.abacus.util.u.OptionalFloat;
import com.landawn.abacus.util.function.FloatBiFunction;
import com.landawn.abacus.util.function.FloatBiPredicate;
import com.landawn.abacus.util.function.FloatBinaryOperator;
import com.landawn.abacus.util.function.FloatConsumer;
import com.landawn.abacus.util.function.FloatFunction;
import com.landawn.abacus.util.function.FloatNFunction;
import com.landawn.abacus.util.function.FloatPredicate;
import com.landawn.abacus.util.function.FloatSupplier;
import com.landawn.abacus.util.function.FloatTernaryOperator;
import com.landawn.abacus.util.function.FloatToDoubleFunction;
import com.landawn.abacus.util.function.FloatToIntFunction;
import com.landawn.abacus.util.function.FloatToLongFunction;
import com.landawn.abacus.util.function.FloatTriPredicate;
import com.landawn.abacus.util.function.FloatUnaryOperator;
import com.landawn.abacus.util.function.ObjFloatConsumer;
import com.landawn.abacus.util.function.ToFloatFunction;

/**
 * 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 FloatStream
        extends StreamBase {

    static final Random RAND = new SecureRandom();

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

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

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

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

    @Override
    public FloatStream skipUntil(final FloatPredicate predicate) {
        assertNotClosed();

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

    @ParallelSupported
    @IntermediateOp
    public abstract FloatStream map(FloatUnaryOperator mapper);

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

    @ParallelSupported
    @IntermediateOp
    public abstract LongStream mapToLong(FloatToLongFunction mapper);

    @ParallelSupported
    @IntermediateOp
    public abstract DoubleStream mapToDouble(FloatToDoubleFunction mapper);

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

    @ParallelSupported
    @IntermediateOp
    public abstract FloatStream flatMap(FloatFunction mapper);

    // public abstract FloatStream flatmap(FloatFunction mapper);

    @ParallelSupported
    @IntermediateOp
    public abstract FloatStream flatmap(FloatFunction mapper); //NOSONAR

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

    @ParallelSupported
    @IntermediateOp
    public abstract LongStream flatMapToLong(FloatFunction mapper);

    @ParallelSupported
    @IntermediateOp
    public abstract DoubleStream flatMapToDouble(FloatFunction mapper);

    @ParallelSupported
    @IntermediateOp
    public abstract  Stream flatMapToObj(FloatFunction> mapper); //NOSONAR

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

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

    /**
     * Note: copied from StreamEx: https://github.com/amaembo/streamex
     *
     * @param 
     * @param mapper
     * @return
     */
    @Beta
    @ParallelSupported
    @IntermediateOp
    public abstract FloatStream mapPartial(FloatFunction 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(FloatBiPredicate, FloatBinaryOperator) * @see Stream#rangeMap(BiPredicate, BiFunction) */ @SequentialOnly @IntermediateOp public abstract FloatStream rangeMap(final FloatBiPredicate sameRange, final FloatBinaryOperator 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 FloatBiPredicate sameRange, final FloatBiFunction 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 FloatBiPredicate collapsible); /** * 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 * @param mergeFunction * @return */ @SequentialOnly @IntermediateOp public abstract FloatStream collapse(final FloatBiPredicate collapsible, final FloatBinaryOperator 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 FloatStream collapse(final FloatTriPredicate collapsible, final FloatBinaryOperator 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 FloatStream scan(final FloatBinaryOperator 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 FloatStream scan(final float init, final FloatBinaryOperator accumulator); /** * * @param init * @param accumulator * @param initIncluded * @return */ @SequentialOnly @IntermediateOp public abstract FloatStream scan(final float init, final FloatBinaryOperator accumulator, final boolean initIncluded); @SequentialOnly @IntermediateOp public abstract FloatStream prepend(final float... a); @SequentialOnly @IntermediateOp public abstract FloatStream append(final float... a); @SequentialOnly @IntermediateOp public abstract FloatStream appendIfEmpty(final float... a); /** *
* This method only runs sequentially, even in parallel stream. * * @param n * @return */ @SequentialOnly @IntermediateOp public abstract FloatStream top(int n); /** *
* This method only runs sequentially, even in parallel stream. * * @param n * @return */ @SequentialOnly @IntermediateOp public abstract FloatStream top(final int n, Comparator comparator); @SequentialOnly @TerminalOp public abstract FloatList toFloatList(); /** * * @param keyMapper * @param valueMapper * @return * @see Collectors#toMap(Throwables.Function, Throwables.Function) */ @ParallelSupported @TerminalOp public abstract Map toMap(Throwables.FloatFunction keyMapper, Throwables.FloatFunction 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.FloatFunction keyMapper, Throwables.FloatFunction 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.FloatFunction keyMapper, Throwables.FloatFunction 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.FloatFunction keyMapper, Throwables.FloatFunction 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.FloatFunction 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.FloatFunction keyMapper, final Collector downstream, final Supplier mapFactory) throws E; @ParallelSupported @TerminalOp public abstract float reduce(float identity, FloatBinaryOperator op); @ParallelSupported @TerminalOp public abstract OptionalFloat reduce(FloatBinaryOperator op); /** * * @param * @param supplier * @param accumulator * @param combiner * @return * @see Stream#collect(Supplier, BiConsumer, BiConsumer) */ @ParallelSupported @TerminalOp public abstract R collect(Supplier supplier, ObjFloatConsumer 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, ObjFloatConsumer, BiConsumer)}. * * @param supplier * @param accumulator * @return * @see #collect(Supplier, ObjFloatConsumer, BiConsumer) * @see Stream#collect(Supplier, BiConsumer) * @see Stream#collect(Supplier, BiConsumer, BiConsumer) */ @ParallelSupported @TerminalOp public abstract R collect(Supplier supplier, ObjFloatConsumer accumulator); @ParallelSupported @TerminalOp public abstract void forEach(final Throwables.FloatConsumer action) throws E; @ParallelSupported @TerminalOp public abstract void forEachIndexed(Throwables.IndexedFloatConsumer action) throws E; @ParallelSupported @TerminalOp public abstract boolean anyMatch(final Throwables.FloatPredicate predicate) throws E; @ParallelSupported @TerminalOp public abstract boolean allMatch(final Throwables.FloatPredicate predicate) throws E; @ParallelSupported @TerminalOp public abstract boolean noneMatch(final Throwables.FloatPredicate predicate) throws E; @ParallelSupported @TerminalOp public abstract OptionalFloat findFirst(final Throwables.FloatPredicate 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 OptionalFloat} will be returned. * * @param * @param predicateForFirst * @return * @throws E */ @ParallelSupported @TerminalOp public abstract OptionalFloat findFirstOrAny(Throwables.FloatPredicate 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 OptionalFloat} will be returned. * * @param * @param predicateForFirst * @return * @throws E */ @ParallelSupported @TerminalOp public abstract OptionalFloat findFirstOrLast(Throwables.FloatPredicate 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 OptionalFloat findLast(final Throwables.FloatPredicate predicate) throws E; @ParallelSupported @TerminalOp public abstract OptionalFloat findAny(final Throwables.FloatPredicate predicate) throws E; @SequentialOnly @TerminalOp public abstract OptionalFloat min(); @SequentialOnly @TerminalOp public abstract OptionalFloat 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 OptionalFloat kthLargest(int k); @SequentialOnly @TerminalOp public abstract double sum(); @SequentialOnly @TerminalOp public abstract OptionalDouble average(); @SequentialOnly @TerminalOp public abstract FloatSummaryStatistics 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(FloatStream, FloatBiFunction)} // * @see #mergeWith(FloatStream, FloatBiFunction) // */ // @SequentialOnly // @IntermediateOp // @Deprecated // public FloatStream merge(final FloatStream b, final FloatBiFunction 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 FloatStream mergeWith(final FloatStream b, final FloatBiFunction nextSelector); @ParallelSupported @IntermediateOp public abstract FloatStream zipWith(FloatStream b, FloatBinaryOperator zipFunction); @ParallelSupported @IntermediateOp public abstract FloatStream zipWith(FloatStream b, FloatStream c, FloatTernaryOperator zipFunction); @ParallelSupported @IntermediateOp public abstract FloatStream zipWith(FloatStream b, float valueForNoneA, float valueForNoneB, FloatBinaryOperator zipFunction); @ParallelSupported @IntermediateOp public abstract FloatStream zipWith(FloatStream b, FloatStream c, float valueForNoneA, float valueForNoneB, float valueForNoneC, FloatTernaryOperator zipFunction); @SequentialOnly @IntermediateOp public abstract DoubleStream asDoubleStream(); @SequentialOnly @IntermediateOp public abstract Stream boxed(); /** * Remember to close this Stream after the iteration is done, if needed. * * @return */ @SequentialOnly @Override public FloatIterator iterator() { assertNotClosed(); if (!isEmptyCloseHandlers(closeHandlers) && logger.isWarnEnabled()) { logger.warn("### Remember to close " + ClassUtil.getSimpleClassName(getClass())); } return iteratorEx(); } abstract FloatIteratorEx iteratorEx(); public static FloatStream empty() { return new ArrayFloatStream(N.EMPTY_FLOAT_ARRAY, true, null); } public static FloatStream ofNullable(final Float e) { return e == null ? empty() : of(e); } @SafeVarargs public static FloatStream of(final float... a) { return N.isNullOrEmpty(a) ? empty() : new ArrayFloatStream(a); } public static FloatStream of(final float[] a, final int startIndex, final int endIndex) { return N.isNullOrEmpty(a) && (startIndex == 0 && endIndex == 0) ? empty() : new ArrayFloatStream(a, startIndex, endIndex); } public static FloatStream of(final Float[] a) { return Stream.of(a).mapToFloat(FnF.unbox()); } public static FloatStream of(final Float[] a, final int startIndex, final int endIndex) { return Stream.of(a, startIndex, endIndex).mapToFloat(FnF.unbox()); } public static FloatStream of(final Collection c) { return Stream.of(c).mapToFloat(FnF.unbox()); } public static FloatStream of(final FloatIterator iterator) { return iterator == null ? empty() : new IteratorFloatStream(iterator); } public static FloatStream of(final FloatBuffer buf) { if (buf == null) { return empty(); } return IntStream.range(buf.position(), buf.limit()).mapToFloat(buf::get); } /** * Lazy evaluation. *
* * This is equal to: {@code Stream.just(supplier).flatMapToFloat(it -> it.get())}. * * @param * @param supplier * @return */ public static FloatStream defer(final Supplier supplier) { N.checkArgNotNull(supplier, "supplier"); return Stream.just(supplier).flatMapToFloat(Supplier::get); } // /** // * Lazy evaluation. // *
// * // * This is equal to: {@code Stream.just(supplier).flatMapToFloat(it -> it.get().stream())}. // * // * @param supplier // * @return // */ // @Beta // public static FloatStream from(final Supplier supplier) { // N.checkArgNotNull(supplier, "supplier"); // // return Stream.just(supplier).flatMapToFloat(it -> it.get().stream()); // } private static final Function flatMapper = FloatStream::of; private static final Function flattMapper = FloatStream::flatten; public static FloatStream flatten(final float[][] a) { return N.isNullOrEmpty(a) ? empty() : Stream.of(a).flatMapToFloat(flatMapper); } public static FloatStream flatten(final float[][] 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).flatMapToFloat(flatMapper); } long n = 0; for (float[] e : a) { n += N.len(e); } if (n == 0) { return empty(); } final int rows = N.len(a); final long count = n; final FloatIterator iter = new FloatIteratorEx() { private int rowNum = 0; private int colNum = 0; private long cnt = 0; @Override public boolean hasNext() { return cnt < count; } @Override public float nextFloat() { 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 FloatStream flatten(final float[][] a, final float 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 (float[] 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; FloatIterator iter = null; if (vertically) { iter = new FloatIteratorEx() { private int rowNum = 0; private int colNum = 0; private long cnt = 0; @Override public boolean hasNext() { return cnt < count; } @Override public float nextFloat() { 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 FloatIteratorEx() { private int rowNum = 0; private int colNum = 0; private long cnt = 0; @Override public boolean hasNext() { return cnt < count; } @Override public float nextFloat() { 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 FloatStream flatten(final float[][][] a) { return N.isNullOrEmpty(a) ? empty() : Stream.of(a).flatMapToFloat(flattMapper); } public static FloatStream repeat(final float 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 IteratorFloatStream(new FloatIteratorEx() { private long cnt = n; @Override public boolean hasNext() { return cnt > 0; } @Override public float nextFloat() { 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 float[] toArray() { final float[] result = new float[(int) cnt]; for (int i = 0; i < cnt; i++) { result[i] = element; } cnt = 0; return result; } }); } public static FloatStream random() { return generate(RAND::nextFloat); } public static FloatStream iterate(final BooleanSupplier hasNext, final FloatSupplier next) { N.checkArgNotNull(hasNext); N.checkArgNotNull(next); return new IteratorFloatStream(new FloatIteratorEx() { private boolean hasNextVal = false; @Override public boolean hasNext() { if (!hasNextVal) { hasNextVal = hasNext.getAsBoolean(); } return hasNextVal; } @Override public float nextFloat() { if (!hasNextVal && !hasNext()) { throw new NoSuchElementException(); } hasNextVal = false; return next.getAsFloat(); } }); } public static FloatStream iterate(final float init, final BooleanSupplier hasNext, final FloatUnaryOperator f) { N.checkArgNotNull(hasNext); N.checkArgNotNull(f); return new IteratorFloatStream(new FloatIteratorEx() { private float t = 0; private boolean isFirst = true; private boolean hasNextVal = false; @Override public boolean hasNext() { if (!hasNextVal) { hasNextVal = hasNext.getAsBoolean(); } return hasNextVal; } @Override public float nextFloat() { if (!hasNextVal && !hasNext()) { throw new NoSuchElementException(); } hasNextVal = false; if (isFirst) { isFirst = false; t = init; } else { t = f.applyAsFloat(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 FloatStream iterate(final float init, final FloatPredicate hasNext, final FloatUnaryOperator f) { N.checkArgNotNull(hasNext); N.checkArgNotNull(f); return new IteratorFloatStream(new FloatIteratorEx() { private float t = 0; private float 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.applyAsFloat(t)); } if (!hasNextVal) { hasMore = false; } } return hasNextVal; } @Override public float nextFloat() { if (!hasNextVal && !hasNext()) { throw new NoSuchElementException(); } t = cur; hasNextVal = false; return t; } }); } public static FloatStream iterate(final float init, final FloatUnaryOperator f) { N.checkArgNotNull(f); return new IteratorFloatStream(new FloatIteratorEx() { private float t = 0; private boolean isFirst = true; @Override public boolean hasNext() { return true; } @Override public float nextFloat() { if (isFirst) { isFirst = false; t = init; } else { t = f.applyAsFloat(t); } return t; } }); } public static FloatStream generate(final FloatSupplier s) { N.checkArgNotNull(s); return new IteratorFloatStream(new FloatIteratorEx() { @Override public boolean hasNext() { return true; } @Override public float nextFloat() { return s.getAsFloat(); } }); } @SafeVarargs public static FloatStream concat(final float[]... a) { if (N.isNullOrEmpty(a)) { return empty(); } return concat(Arrays.asList(a)); } @SafeVarargs public static FloatStream concat(final FloatIterator... a) { if (N.isNullOrEmpty(a)) { return empty(); } return concatIterators(Array.asList(a)); } @SafeVarargs public static FloatStream concat(final FloatStream... a) { if (N.isNullOrEmpty(a)) { return empty(); } return concat(Array.asList(a)); } @Beta public static FloatStream concat(final List c) { if (N.isNullOrEmpty(c)) { return empty(); } return of(new FloatIteratorEx() { private final Iterator iter = c.iterator(); private float[] 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 float nextFloat() { if ((cur == null || cursor >= cur.length) && !hasNext()) { throw new NoSuchElementException(); } return cur[cursor++]; } }); } public static FloatStream concat(final Collection c) { return N.isNullOrEmpty(c) ? empty() : new IteratorFloatStream(new FloatIteratorEx() { //NOSONAR private final Iterator iterators = c.iterator(); private FloatStream cur; private FloatIterator 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 float nextFloat() { if ((iter == null || !iter.hasNext()) && !hasNext()) { throw new NoSuchElementException(); } return iter.nextFloat(); } }).onClose(newCloseHandler(c)); } @Beta public static FloatStream concatIterators(final Collection c) { if (N.isNullOrEmpty(c)) { return empty(); } return new IteratorFloatStream(new FloatIteratorEx() { private final Iterator iter = c.iterator(); private FloatIterator cur; @Override public boolean hasNext() { while ((cur == null || !cur.hasNext()) && iter.hasNext()) { cur = iter.next(); } return cur != null && cur.hasNext(); } @Override public float nextFloat() { if ((cur == null || !cur.hasNext()) && !hasNext()) { throw new NoSuchElementException(); } return cur.nextFloat(); } }); } /** * 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 FloatStream zip(final float[] a, final float[] b, final FloatBinaryOperator zipFunction) { if (N.isNullOrEmpty(a) || N.isNullOrEmpty(b)) { return empty(); } return new IteratorFloatStream(new FloatIteratorEx() { 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 float nextFloat() { if (cursor >= len) { throw new NoSuchElementException(); } return zipFunction.applyAsFloat(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 FloatStream zip(final float[] a, final float[] b, final float[] c, final FloatTernaryOperator zipFunction) { if (N.isNullOrEmpty(a) || N.isNullOrEmpty(b) || N.isNullOrEmpty(c)) { return empty(); } return new IteratorFloatStream(new FloatIteratorEx() { 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 float nextFloat() { if (cursor >= len) { throw new NoSuchElementException(); } return zipFunction.applyAsFloat(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 FloatStream zip(final FloatIterator a, final FloatIterator b, final FloatBinaryOperator zipFunction) { return new IteratorFloatStream(new FloatIteratorEx() { private final FloatIterator iterA = a == null ? FloatIterator.empty() : a; private final FloatIterator iterB = b == null ? FloatIterator.empty() : b; @Override public boolean hasNext() { return iterA.hasNext() && iterB.hasNext(); } @Override public float nextFloat() { return zipFunction.applyAsFloat(iterA.nextFloat(), iterB.nextFloat()); } }); } /** * 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 FloatStream zip(final FloatIterator a, final FloatIterator b, final FloatIterator c, final FloatTernaryOperator zipFunction) { return new IteratorFloatStream(new FloatIteratorEx() { private final FloatIterator iterA = a == null ? FloatIterator.empty() : a; private final FloatIterator iterB = b == null ? FloatIterator.empty() : b; private final FloatIterator iterC = c == null ? FloatIterator.empty() : c; @Override public boolean hasNext() { return iterA.hasNext() && iterB.hasNext() && iterC.hasNext(); } @Override public float nextFloat() { return zipFunction.applyAsFloat(iterA.nextFloat(), iterB.nextFloat(), iterC.nextFloat()); } }); } /** * 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 FloatStream zip(final FloatStream a, final FloatStream b, final FloatBinaryOperator 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 FloatStream zip(final FloatStream a, final FloatStream b, final FloatStream c, final FloatTernaryOperator 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 FloatStream zip(final Collection c, final FloatNFunction zipFunction) { return Stream.zip(c, zipFunction).mapToFloat(ToFloatFunction.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 FloatStream zip(final float[] a, final float[] b, final float valueForNoneA, final float valueForNoneB, final FloatBinaryOperator zipFunction) { if (N.isNullOrEmpty(a) && N.isNullOrEmpty(b)) { return empty(); } return new IteratorFloatStream(new FloatIteratorEx() { private final int aLen = N.len(a), bLen = N.len(b), len = N.max(aLen, bLen); private int cursor = 0; private float ret = 0; @Override public boolean hasNext() { return cursor < len; } @Override public float nextFloat() { if (cursor >= len) { throw new NoSuchElementException(); } ret = zipFunction.applyAsFloat(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 FloatStream zip(final float[] a, final float[] b, final float[] c, final float valueForNoneA, final float valueForNoneB, final float valueForNoneC, final FloatTernaryOperator zipFunction) { if (N.isNullOrEmpty(a) && N.isNullOrEmpty(b) && N.isNullOrEmpty(c)) { return empty(); } return new IteratorFloatStream(new FloatIteratorEx() { 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 float ret = 0; @Override public boolean hasNext() { return cursor < len; } @Override public float nextFloat() { if (cursor >= len) { throw new NoSuchElementException(); } ret = zipFunction.applyAsFloat(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 FloatStream zip(final FloatIterator a, final FloatIterator b, final float valueForNoneA, final float valueForNoneB, final FloatBinaryOperator zipFunction) { return new IteratorFloatStream(new FloatIteratorEx() { private final FloatIterator iterA = a == null ? FloatIterator.empty() : a; private final FloatIterator iterB = b == null ? FloatIterator.empty() : b; @Override public boolean hasNext() { return iterA.hasNext() || iterB.hasNext(); } @Override public float nextFloat() { if (iterA.hasNext()) { return zipFunction.applyAsFloat(iterA.nextFloat(), iterB.hasNext() ? iterB.nextFloat() : valueForNoneB); } else { return zipFunction.applyAsFloat(valueForNoneA, iterB.nextFloat()); } } }); } /** * 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 FloatStream zip(final FloatIterator a, final FloatIterator b, final FloatIterator c, final float valueForNoneA, final float valueForNoneB, final float valueForNoneC, final FloatTernaryOperator zipFunction) { return new IteratorFloatStream(new FloatIteratorEx() { private final FloatIterator iterA = a == null ? FloatIterator.empty() : a; private final FloatIterator iterB = b == null ? FloatIterator.empty() : b; private final FloatIterator iterC = c == null ? FloatIterator.empty() : c; @Override public boolean hasNext() { return iterA.hasNext() || iterB.hasNext() || iterC.hasNext(); } @Override public float nextFloat() { if (iterA.hasNext()) { return zipFunction.applyAsFloat(iterA.nextFloat(), iterB.hasNext() ? iterB.nextFloat() : valueForNoneB, iterC.hasNext() ? iterC.nextFloat() : valueForNoneC); } else if (iterB.hasNext()) { return zipFunction.applyAsFloat(valueForNoneA, iterB.nextFloat(), iterC.hasNext() ? iterC.nextFloat() : valueForNoneC); } else { return zipFunction.applyAsFloat(valueForNoneA, valueForNoneB, iterC.nextFloat()); } } }); } /** * 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 FloatStream zip(final FloatStream a, final FloatStream b, final float valueForNoneA, final float valueForNoneB, final FloatBinaryOperator 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 FloatStream zip(final FloatStream a, final FloatStream b, final FloatStream c, final float valueForNoneA, final float valueForNoneB, final float valueForNoneC, final FloatTernaryOperator 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 FloatStream zip(final Collection c, final float[] valuesForNone, final FloatNFunction zipFunction) { return Stream.zip(c, valuesForNone, zipFunction).mapToFloat(ToFloatFunction.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 FloatStream merge(final float[] a, final float[] b, final FloatBiFunction nextSelector) { if (N.isNullOrEmpty(a)) { return of(b); } else if (N.isNullOrEmpty(b)) { return of(a); } return new IteratorFloatStream(new FloatIteratorEx() { 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 float nextFloat() { 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 FloatStream merge(final float[] a, final float[] b, final float[] c, final FloatBiFunction nextSelector) { return merge(merge(a, b, nextSelector).iteratorEx(), FloatStream.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 FloatStream merge(final FloatIterator a, final FloatIterator b, final FloatBiFunction nextSelector) { return new IteratorFloatStream(new FloatIteratorEx() { private final FloatIterator iterA = a == null ? FloatIterator.empty() : a; private final FloatIterator iterB = b == null ? FloatIterator.empty() : b; private float nextA = 0; private float nextB = 0; private boolean hasNextA = false; private boolean hasNextB = false; @Override public boolean hasNext() { return iterA.hasNext() || iterB.hasNext() || hasNextA || hasNextB; } @Override public float nextFloat() { if (hasNextA) { if (iterB.hasNext()) { if (nextSelector.apply(nextA, (nextB = iterB.nextFloat())) == 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.nextFloat()), 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.nextFloat()), (nextB = iterB.nextFloat())) == MergeResult.TAKE_FIRST) { hasNextB = true; return nextA; } else { hasNextA = true; return nextB; } } else { return iterA.nextFloat(); } } else if (iterB.hasNext()) { return iterB.nextFloat(); } 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 FloatStream merge(final FloatIterator a, final FloatIterator b, final FloatIterator c, final FloatBiFunction 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 FloatStream merge(final FloatStream a, final FloatStream b, final FloatBiFunction 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 FloatStream merge(final FloatStream a, final FloatStream b, final FloatStream c, final FloatBiFunction 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 FloatStream merge(final Collection c, final FloatBiFunction 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(); FloatStream 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 FloatStream parallelMerge(final Collection c, final FloatBiFunction 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 FloatStream parallelMerge(final Collection c, final FloatBiFunction 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, () -> { FloatStream a = null; FloatStream b = null; FloatStream 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 = FloatStream.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).flatMapToFloat(Supplier::get); } public abstract static class FloatStreamEx extends FloatStream { private FloatStreamEx(boolean sorted, Collection closeHandlers) { //NOSONAR super(sorted, closeHandlers); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy