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

com.annimon.stream.DoubleStream Maven / Gradle / Ivy

The newest version!
package com.annimon.stream;

import java.io.Closeable;
import java.util.Comparator;

import com.annimon.stream.internal.Compose;
import com.annimon.stream.internal.Operators;
import com.annimon.stream.internal.Params;
import com.annimon.stream.iterator.PrimitiveExtIterator.OfDouble;
import com.annimon.stream.iterator.PrimitiveIterator;
import com.annimon.stream.operator.DoubleArray;
import com.annimon.stream.operator.DoubleConcat;
import com.annimon.stream.operator.DoubleDropWhile;
import com.annimon.stream.operator.DoubleFilter;
import com.annimon.stream.operator.DoubleFlatMap;
import com.annimon.stream.operator.DoubleGenerate;
import com.annimon.stream.operator.DoubleIterate;
import com.annimon.stream.operator.DoubleLimit;
import com.annimon.stream.operator.DoubleMap;
import com.annimon.stream.operator.DoubleMapToInt;
import com.annimon.stream.operator.DoubleMapToLong;
import com.annimon.stream.operator.DoubleMapToObj;
import com.annimon.stream.operator.DoublePeek;
import com.annimon.stream.operator.DoubleScan;
import com.annimon.stream.operator.DoubleScanIdentity;
import com.annimon.stream.operator.DoubleSkip;
import com.annimon.stream.operator.DoubleSorted;
import com.annimon.stream.operator.DoubleTakeUntil;
import com.annimon.stream.operator.DoubleTakeWhile;
import com.landawn.abacus.util.N;
import com.landawn.abacus.util.OptionalDouble;
import com.landawn.abacus.util.function.DoubleBinaryOperator;
import com.landawn.abacus.util.function.DoubleConsumer;
import com.landawn.abacus.util.function.DoubleFunction;
import com.landawn.abacus.util.function.DoublePredicate;
import com.landawn.abacus.util.function.DoubleSupplier;
import com.landawn.abacus.util.function.DoubleToIntFunction;
import com.landawn.abacus.util.function.DoubleToLongFunction;
import com.landawn.abacus.util.function.DoubleUnaryOperator;
import com.landawn.abacus.util.function.Function;
import com.landawn.abacus.util.function.ObjDoubleConsumer;
import com.landawn.abacus.util.function.Supplier;
import com.landawn.abacus.util.function.ToDoubleFunction;

/**
 * A sequence of {@code double}-valued elements supporting aggregate operations.
 *
 * @since 1.1.4
 * @see Stream
 */
public final class DoubleStream implements Closeable {

    /**
     * Single instance for empty stream. It is safe for multi-thread environment because it has no content.
     */
    private static final DoubleStream EMPTY = new DoubleStream(new PrimitiveIterator.OfDouble() {

        @Override
        public boolean hasNext() {
            return false;
        }

        @Override
        public double nextDouble() {
            return 0d;
        }
    });

    /**
     * Returns an empty stream.
     *
     * @return the empty stream
     */
    public static DoubleStream empty() {
        return EMPTY;
    }

    /**
     * Creates a {@code DoubleStream} from the specified values.
     *
     * @param values  the elements of the new stream
     * @return the new stream
     * @throws NullPointerException if {@code values} is null
     */
    public static DoubleStream of(final double... values) {
        if (values == null || values.length == 0) {
            return DoubleStream.empty();
        }

        return new DoubleStream(new DoubleArray(values));
    }

    /**
     * Creates a {@code DoubleStream} from {@code PrimitiveIterator.OfDouble}.
     *
     * @param iterator  the iterator with elements to be passed to stream
     * @return the new {@code DoubleStream}
     * @throws NullPointerException if {@code iterator} is null
     */
    public static DoubleStream of(PrimitiveIterator.OfDouble iterator) {
        N.requireNonNull(iterator);
        return new DoubleStream(iterator);
    }

    /**
     * Creates a {@code DoubleStream} by elements that generated by {@code DoubleSupplier}.
     *
     * @param s  the {@code DoubleSupplier} for generated elements
     * @return a new infinite sequential {@code DoubleStream}
     * @throws NullPointerException if {@code s} is null
     */
    public static DoubleStream generate(final DoubleSupplier s) {
        N.requireNonNull(s);
        return new DoubleStream(new DoubleGenerate(s));
    }

    /**
     * Creates a {@code DoubleStream} by iterative application {@code DoubleUnaryOperator} function
     * to an initial element {@code seed}. Produces {@code DoubleStream} consisting of
     * {@code seed}, {@code f(seed)}, {@code f(f(seed))}, etc.
     *
     * 

The first element (position {@code 0}) in the {@code DoubleStream} will be * the provided {@code seed}. For {@code n > 0}, the element at position * {@code n}, will be the result of applying the function {@code f} to the * element at position {@code n - 1}. * *

Example: *

     * seed: 1
     * f: (a) -> a + 5
     * result: [1, 6, 11, 16, ...]
     * 
* * @param seed the initial element * @param f a function to be applied to the previous element to produce a new element * @return a new sequential {@code DoubleStream} * @throws NullPointerException if {@code f} is null */ public static DoubleStream iterate(final double seed, final DoubleUnaryOperator f) { N.requireNonNull(f); return new DoubleStream(new DoubleIterate(seed, f)); } /** * Creates an {@code DoubleStream} by iterative application {@code DoubleUnaryOperator} function * to an initial element {@code seed}, conditioned on satisfying the supplied predicate. * *

Example: *

     * seed: 0.0
     * predicate: (a) -> a < 0.2
     * f: (a) -> a + 0.05
     * result: [0.0, 0.05, 0.1, 0.15]
     * 
* * @param seed the initial value * @param predicate a predicate to determine when the stream must terminate * @param op operator to produce new element by previous one * @return the new stream * @throws NullPointerException if {@code op} is null * @since 1.1.5 */ public static DoubleStream iterate(final double seed, final DoublePredicate predicate, final DoubleUnaryOperator op) { N.requireNonNull(predicate); return iterate(seed, op).takeWhile(predicate); } /** * Concatenates two streams. * *

Example: *

     * stream a: [1, 2, 3, 4]
     * stream b: [5, 6]
     * result:   [1, 2, 3, 4, 5, 6]
     * 
* * @param a the first stream * @param b the second stream * @return the new concatenated stream * @throws NullPointerException if {@code a} or {@code b} is null */ public static DoubleStream concat(final DoubleStream a, final DoubleStream b) { N.requireNonNull(a); N.requireNonNull(b); @SuppressWarnings("resource") DoubleStream result = new DoubleStream(new DoubleConcat(a.iterator, b.iterator)); return result.onClose(Compose.closeables(a, b)); } public static DoubleStream concat(final double[] a, final double[] b) { return new DoubleStream(new DoubleConcat(OfDouble.of(a), OfDouble.of(b))); } private final PrimitiveIterator.OfDouble iterator; private final Params params; private DoubleStream(PrimitiveIterator.OfDouble iterator) { this(null, iterator); } DoubleStream(Params params, PrimitiveIterator.OfDouble iterator) { this.params = params; this.iterator = iterator; } /** * Returns internal {@code DoubleStream} iterator. * * @return internal {@code DoubleStream} iterator. */ public PrimitiveIterator.OfDouble iterator() { return iterator; } /** * Returns a {@code Stream} consisting of the elements of this stream, * each boxed to an {@code Double}. * *

This is an lazy intermediate operation. * * @return a {@code Stream} consistent of the elements of this stream, * each boxed to an {@code Double} */ public Stream boxed() { return new Stream<>(params, iterator); } /** * Returns {@code DoubleStream} with elements that satisfy the given predicate. * *

This is an intermediate operation. * *

Example: *

     * predicate: (a) -> a > 2
     * stream: [1, 2, 3, 4, -8, 0, 11]
     * result: [3, 4, 11]
     * 
* * @param predicate the predicate used to filter elements * @return the new stream */ public DoubleStream filter(final DoublePredicate predicate) { return new DoubleStream(params, new DoubleFilter(iterator, predicate)); } /** * Returns an {@code DoubleStream} consisting of the results of applying the given * function to the elements of this stream. * *

This is an intermediate operation. * *

Example: *

     * mapper: (a) -> a + 5
     * stream: [1, 2, 3, 4]
     * result: [6, 7, 8, 9]
     * 
* * @param mapper the mapper function used to apply to each element * @return the new stream * @see Stream#map(com.landawn.abacus.util.function.Function) */ public DoubleStream map(final DoubleUnaryOperator mapper) { return new DoubleStream(params, new DoubleMap(iterator, mapper)); } /** * Returns a {@code Stream} consisting of the results of applying the given * function to the elements of this stream. * *

This is an intermediate operation. * * @param the type result * @param mapper the mapper function used to apply to each element * @return the new {@code Stream} */ public Stream mapToObj(final DoubleFunction mapper) { return new Stream<>(params, new DoubleMapToObj<>(iterator, mapper)); } /** * Returns an {@code IntStream} consisting of the results of applying the given * function to the elements of this stream. * *

This is an intermediate operation. * * @param mapper the mapper function used to apply to each element * @return the new {@code IntStream} */ public IntStream mapToInt(final DoubleToIntFunction mapper) { return new IntStream(params, new DoubleMapToInt(iterator, mapper)); } /** * Returns an {@code LongStream} consisting of the results of applying the given * function to the elements of this stream. * *

This is an intermediate operation. * * @param mapper the mapper function used to apply to each element * @return the new {@code LongStream} */ public LongStream mapToLong(final DoubleToLongFunction mapper) { return new LongStream(params, new DoubleMapToLong(iterator, mapper)); } /** * Returns a stream consisting of the results of replacing each element of * this stream with the contents of a mapped stream produced by applying * the provided mapping function to each element. * *

This is an intermediate operation. * *

Example: *

     * mapper: (a) -> [a, a + 5]
     * stream: [1, 2, 3, 4]
     * result: [1, 6, 2, 7, 3, 8, 4, 9]
     * 
* * @param mapper the mapper function used to apply to each element * @return the new stream * @see Stream#flatMap(com.landawn.abacus.util.function.Function) */ public DoubleStream flatMap(final DoubleFunction mapper) { return new DoubleStream(params, new DoubleFlatMap(iterator, mapper)); } /** * Returns a stream consisting of the distinct elements of this stream. * *

This is a stateful intermediate operation. * *

Example: *

     * stream: [1, 4, 2, 3, 3, 4, 1]
     * result: [1, 4, 2, 3]
     * 
* * @return the new stream */ public DoubleStream distinct() { return boxed().distinct().mapToDouble(UNBOX_FUNCTION); } /** * Returns a stream consisting of the elements of this stream in sorted order. * *

This is a stateful intermediate operation. * *

Example: *

     * stream: [3, 4, 1, 2]
     * result: [1, 2, 3, 4]
     * 
* * @return the new stream */ public DoubleStream sorted() { return new DoubleStream(params, new DoubleSorted(iterator)); } /** * Returns a stream consisting of the elements of this stream * in sorted order as determinated by provided {@code Comparator}. * *

This is a stateful intermediate operation. * *

Example: *

     * comparator: (a, b) -> -a.compareTo(b)
     * stream: [1, 2, 3, 4]
     * result: [4, 3, 2, 1]
     * 
* * @param comparator the {@code Comparator} to compare elements * @return the new {@code DoubleStream} */ public DoubleStream sorted(Comparator comparator) { return boxed().sorted(comparator).mapToDouble(UNBOX_FUNCTION); } /** * Performs provided action on each element. * *

This is an intermediate operation. * * @param action the action to be performed on each element * @return the new stream */ public DoubleStream peek(final DoubleConsumer action) { return new DoubleStream(params, new DoublePeek(iterator, action)); } /** * Returns a {@code DoubleStream} produced by iterative application of a accumulation function * to reduction value and next element of the current stream. * Produces a {@code DoubleStream} consisting of {@code value1}, {@code acc(value1, value2)}, * {@code acc(acc(value1, value2), value3)}, etc. * *

This is an intermediate operation. * *

Example: *

     * accumulator: (a, b) -> a + b
     * stream: [1, 2, 3, 4, 5]
     * result: [1, 3, 6, 10, 15]
     * 
* * @param accumulator the accumulation function * @return the new stream * @throws NullPointerException if {@code accumulator} is null * @since 1.1.6 */ public DoubleStream scan(final DoubleBinaryOperator accumulator) { N.requireNonNull(accumulator); return new DoubleStream(params, new DoubleScan(iterator, accumulator)); } /** * Returns a {@code DoubleStream} produced by iterative application of a accumulation function * to an initial element {@code identity} and next element of the current stream. * Produces a {@code DoubleStream} consisting of {@code identity}, {@code acc(identity, value1)}, * {@code acc(acc(identity, value1), value2)}, etc. * *

This is an intermediate operation. * *

Example: *

     * identity: 0
     * accumulator: (a, b) -> a + b
     * stream: [1, 2, 3, 4, 5]
     * result: [0, 1, 3, 6, 10, 15]
     * 
* * @param identity the initial value * @param accumulator the accumulation function * @return the new stream * @throws NullPointerException if {@code accumulator} is null * @since 1.1.6 */ public DoubleStream scan(final double identity, final DoubleBinaryOperator accumulator) { N.requireNonNull(accumulator); return new DoubleStream(params, new DoubleScanIdentity(iterator, identity, accumulator)); } /** * Takes elements while the predicate returns {@code true}. * *

This is an intermediate operation. * *

Example: *

     * predicate: (a) -> a < 3
     * stream: [1, 2, 3, 4, 1, 2, 3, 4]
     * result: [1, 2]
     * 
* * @param predicate the predicate used to take elements * @return the new {@code DoubleStream} */ public DoubleStream takeWhile(final DoublePredicate predicate) { return new DoubleStream(params, new DoubleTakeWhile(iterator, predicate)); } /** * Takes elements while the predicate returns {@code false}. * Once predicate condition is satisfied by an element, the stream * finishes with this element. * *

This is an intermediate operation. * *

Example: *

     * stopPredicate: (a) -> a > 2
     * stream: [1, 2, 3, 4, 1, 2, 3, 4]
     * result: [1, 2, 3]
     * 
* * @param stopPredicate the predicate used to take elements * @return the new {@code DoubleStream} * @since 1.1.6 */ public DoubleStream takeUntil(final DoublePredicate stopPredicate) { return new DoubleStream(params, new DoubleTakeUntil(iterator, stopPredicate)); } /** * Drops elements while the predicate is true and returns the rest. * *

This is an intermediate operation. * *

Example: *

     * predicate: (a) -> a < 3
     * stream: [1, 2, 3, 4, 1, 2, 3, 4]
     * result: [3, 4, 1, 2, 3, 4]
     * 
* * @param predicate the predicate used to drop elements * @return the new {@code DoubleStream} */ public DoubleStream dropWhile(final DoublePredicate predicate) { return new DoubleStream(params, new DoubleDropWhile(iterator, predicate)); } /** * Returns a stream consisting of the elements of this stream, truncated * to be no longer than {@code maxSize} in length. * *

This is a short-circuiting stateful intermediate operation. * *

Example: *

     * maxSize: 3
     * stream: [1, 2, 3, 4, 5]
     * result: [1, 2, 3]
     *
     * maxSize: 10
     * stream: [1, 2]
     * result: [1, 2]
     * 
* * @param maxSize the number of elements the stream should be limited to * @return the new stream * @throws IllegalArgumentException if {@code maxSize} is negative */ public DoubleStream limit(final long maxSize) { if (maxSize < 0) throw new IllegalArgumentException("maxSize cannot be negative"); if (maxSize == 0) return DoubleStream.empty(); return new DoubleStream(params, new DoubleLimit(iterator, maxSize)); } /** * Skips first {@code n} elements and returns {@code DoubleStream} with remaining elements. * If this stream contains fewer than {@code n} elements, then an * empty stream will be returned. * *

This is a stateful intermediate operation. * *

Example: *

     * n: 3
     * stream: [1, 2, 3, 4, 5]
     * result: [4, 5]
     *
     * n: 10
     * stream: [1, 2]
     * result: []
     * 
* * @param n the number of elements to skip * @return the new stream * @throws IllegalArgumentException if {@code n} is negative */ public DoubleStream skip(final long n) { if (n < 0) throw new IllegalArgumentException("n cannot be negative"); if (n == 0) return this; return new DoubleStream(params, new DoubleSkip(iterator, n)); } /** * Performs an action for each element of this stream. * *

This is a terminal operation. * * @param action the action to be performed on each element */ public void forEach(DoubleConsumer action) { while (iterator.hasNext()) { action.accept(iterator.nextDouble()); } } /** * Performs a reduction on the elements of this stream, using the provided * identity value and an associative accumulation function, and returns the * reduced value. * *

The {@code identity} value must be an identity for the accumulator * function. This means that for all {@code x}, * {@code accumulator.apply(identity, x)} is equal to {@code x}. * The {@code accumulator} function must be an associative function. * *

This is a terminal operation. * *

Example: *

     * identity: 0
     * accumulator: (a, b) -> a + b
     * stream: [1, 2, 3, 4, 5]
     * result: 15
     * 
* * @param identity the identity value for the accumulating function * @param accumulator the accumulation function * @return the result of the reduction * @see #sum() * @see #min() * @see #max() */ public double reduce(double identity, DoubleBinaryOperator accumulator) { double result = identity; while (iterator.hasNext()) { final double value = iterator.nextDouble(); result = accumulator.applyAsDouble(result, value); } return result; } /** * Performs a reduction on the elements of this stream, using an * associative accumulation function, and returns an {@code OptionalDouble} * describing the reduced value, if any. * *

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

This is a terminal operation. * * @param accumulator the accumulation function * @return the result of the reduction * @see #reduce(com.landawn.abacus.util.function.DoubleBinaryOperator) */ public OptionalDouble reduce(DoubleBinaryOperator accumulator) { boolean foundAny = false; double result = 0; while (iterator.hasNext()) { final double value = iterator.nextDouble(); if (!foundAny) { foundAny = true; result = value; } else { result = accumulator.applyAsDouble(result, value); } } return foundAny ? OptionalDouble.of(result) : OptionalDouble.empty(); } /** * Returns an array containing the elements of this stream. * *

This is a terminal operation. * * @return an array containing the elements of this stream */ public double[] toArray() { return Operators.toDoubleArray(iterator); } /** * Collects elements to {@code supplier} provided container by applying the given accumulation function. * *

This is a terminal operation. * * @param the type of the result * @param supplier the supplier function that provides container * @param accumulator the accumulation function * @return the result of collect elements * @see Stream#collect(com.landawn.abacus.util.function.Supplier, com.landawn.abacus.util.function.BiConsumer) */ public R collect(Supplier supplier, ObjDoubleConsumer accumulator) { final R result = supplier.get(); while (iterator.hasNext()) { final double value = iterator.nextDouble(); accumulator.accept(result, value); } return result; } /** * Returns the sum of elements in this stream. * * @return the sum of elements in this stream */ public double sum() { double sum = 0; while (iterator.hasNext()) { sum += iterator.nextDouble(); } return sum; } /** * Returns an {@code OptionalDouble} describing the minimum element of this * stream, or an empty optional if this stream is empty. * *

This is a terminal operation. * * @return the minimum element */ public OptionalDouble min() { return reduce(new DoubleBinaryOperator() { @Override public double applyAsDouble(double left, double right) { return Math.min(left, right); } }); } /** * Returns an {@code OptionalDouble} describing the maximum element of this * stream, or an empty optional if this stream is empty. * *

This is a terminal operation. * * @return the maximum element */ public OptionalDouble max() { return reduce(new DoubleBinaryOperator() { @Override public double applyAsDouble(double left, double right) { return Math.max(left, right); } }); } /** * Returns the count of elements in this stream. * *

This is a terminal operation. * * @return the count of elements in this stream */ public long count() { long count = 0; while (iterator.hasNext()) { iterator.nextDouble(); count++; } return count; } /** * Returns the average of elements in this stream. * *

This is a terminal operation. * * @return the average of elements in this stream */ public OptionalDouble average() { long count = 0; double sum = 0d; while (iterator.hasNext()) { sum += iterator.nextDouble(); count++; } if (count == 0) return OptionalDouble.empty(); return OptionalDouble.of(sum / count); } /** * Tests whether all elements match the given predicate. * May not evaluate the predicate on all elements if not necessary * for determining the result. If the stream is empty then * {@code false} is returned and the predicate is not evaluated. * *

This is a short-circuiting terminal operation. * *

Example: *

     * predicate: (a) -> a == 5
     * stream: [1, 2, 3, 4, 5]
     * result: true
     *
     * predicate: (a) -> a == 5
     * stream: [5, 5, 5]
     * result: true
     * 
* * @param predicate the predicate used to match elements * @return {@code true} if any elements of the stream match the provided * predicate, otherwise {@code false} */ public boolean anyMatch(DoublePredicate predicate) { while (iterator.hasNext()) { if (predicate.test(iterator.nextDouble())) return true; } return false; } /** * Tests whether all elements match the given predicate. * May not evaluate the predicate on all elements if not necessary for * determining the result. If the stream is empty then {@code true} is * returned and the predicate is not evaluated. * *

This is a short-circuiting terminal operation. * *

Example: *

     * predicate: (a) -> a == 5
     * stream: [1, 2, 3, 4, 5]
     * result: false
     *
     * predicate: (a) -> a == 5
     * stream: [5, 5, 5]
     * result: true
     * 
* * @param predicate the predicate used to match elements * @return {@code true} if either all elements of the stream match the * provided predicate or the stream is empty, otherwise {@code false} */ public boolean allMatch(DoublePredicate predicate) { while (iterator.hasNext()) { if (!predicate.test(iterator.nextDouble())) return false; } return true; } /** * Tests whether no elements match the given predicate. * May not evaluate the predicate on all elements if not necessary for * determining the result. If the stream is empty then {@code true} is * returned and the predicate is not evaluated. * *

This is a short-circuiting terminal operation. * *

Example: *

     * predicate: (a) -> a == 5
     * stream: [1, 2, 3, 4, 5]
     * result: false
     *
     * predicate: (a) -> a == 5
     * stream: [1, 2, 3]
     * result: true
     * 
* * @param predicate the predicate used to match elements * @return {@code true} if either no elements of the stream match the * provided predicate or the stream is empty, otherwise {@code false} */ public boolean noneMatch(DoublePredicate predicate) { while (iterator.hasNext()) { if (predicate.test(iterator.nextDouble())) return false; } return true; } /** * Returns the first element wrapped by {@code OptionalDouble} class. * If stream is empty, returns {@code OptionalDouble.empty()}. * *

This is a short-circuiting terminal operation. * * @return an {@code OptionalDouble} with first element * or {@code OptionalDouble.empty()} if stream is empty */ public OptionalDouble findFirst() { if (iterator.hasNext()) { return OptionalDouble.of(iterator.nextDouble()); } return OptionalDouble.empty(); } /** * Returns the last element wrapped by {@code OptionalDouble} class. * If stream is empty, returns {@code OptionalDouble.empty()}. * *

This is a short-circuiting terminal operation. * * @return an {@code OptionalDouble} with the last element * or {@code OptionalDouble.empty()} if the stream is empty * @since 1.1.8 */ public OptionalDouble findLast() { return reduce(new DoubleBinaryOperator() { @Override public double applyAsDouble(double left, double right) { return right; } }); } /** * Applies custom operator on stream. * * Transforming function can return {@code DoubleStream} for intermediate operations, * or any value for terminal operation. * *

Operator examples: *


     *     // Intermediate operator
     *     public class Zip implements Function<DoubleStream, DoubleStream> {
     *
     *         private final DoubleStream secondStream;
     *         private final DoubleBinaryOperator combiner;
     *
     *         public Zip(DoubleStream secondStream, DoubleBinaryOperator combiner) {
     *             this.secondStream = secondStream;
     *             this.combiner = combiner;
     *         }
     *
     *         @Override
     *         public DoubleStream apply(DoubleStream firstStream) {
     *             final PrimitiveIterator.OfDouble it1 = firstStream.iterator();
     *             final PrimitiveIterator.OfDouble it2 = secondStream.iterator();
     *             return DoubleStream.of(new PrimitiveIterator.OfDouble() {
     *                 @Override
     *                 public boolean hasNext() {
     *                     return it1.hasNext() && it2.hasNext();
     *                 }
     *
     *                 @Override
     *                 public double nextDouble() {
     *                     return combiner.applyAsDouble(it1.nextDouble(), it2.nextDouble());
     *                 }
     *             });
     *         }
     *     }
     *
     *     // Intermediate operator based on existing stream operators
     *     public class SkipAndLimit implements UnaryOperator<DoubleStream> {
     *
     *         private final int skip, limit;
     *
     *         public SkipAndLimit(int skip, int limit) {
     *             this.skip = skip;
     *             this.limit = limit;
     *         }
     *
     *         @Override
     *         public DoubleStream apply(DoubleStream stream) {
     *             return stream.skip(skip).limit(limit);
     *         }
     *     }
     *
     *     // Terminal operator
     *     public class DoubleSummaryStatistics implements Function<DoubleStream, double[]> {
     *         @Override
     *         public double[] apply(DoubleStream stream) {
     *             long count = 0;
     *             double sum = 0;
     *             final PrimitiveIterator.OfDouble it = stream.iterator();
     *             while (it.hasNext()) {
     *                 count++;
     *                 sum += it.nextDouble();
     *             }
     *             double average = (count == 0) ? 0 : (sum / (double) count);
     *             return new double[] {count, sum, average};
     *         }
     *     }
     * 
* * @param the type of the result * @param function a transforming function * @return a result of the transforming function * @see Stream#chain(com.landawn.abacus.util.function.Function) * @throws NullPointerException if {@code function} is null */ public R __(Function transfer) { return transfer.apply(this); } public void println() { boxed().println(); } /** * Adds close handler to the current stream. * *

This is an intermediate operation. * * @param closeHandler an action to execute when the stream is closed * @return the new stream with the close handler * @since 1.1.8 */ public DoubleStream onClose(final Runnable closeHandler) { N.requireNonNull(closeHandler); final Params newParams; if (params == null) { newParams = new Params(); newParams.closeHandler = closeHandler; } else { newParams = params; final Runnable firstHandler = newParams.closeHandler; newParams.closeHandler = Compose.runnables(firstHandler, closeHandler); } return new DoubleStream(newParams, iterator); } /** * Causes close handler to be invoked if it exists. * Since most of the stream providers are lists or arrays, * it is not necessary to close the stream. * * @since 1.1.8 */ @Override public void close() { if (params != null && params.closeHandler != null) { params.closeHandler.run(); params.closeHandler = null; } } private static final ToDoubleFunction UNBOX_FUNCTION = new ToDoubleFunction() { @Override public double applyAsDouble(Double t) { return t; } }; }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy