@Override public LongSummaryStatistics summaryStatistics() { return collect(LongSummaryStatistics::new, LongSummaryStatistics::accept, LongSummaryStatistics::combine); }
/** * Returns a {@link String} which is the concatenation of the results of * calling {@link String#valueOf(long)} on each element of this stream, * separated by the specified delimiter, in encounter order. * * <p> * This is a terminal operation. * * @param delimiter the delimiter to be used between each element * @return the result of concatenation. For empty input stream empty String * is returned. * @since 0.3.1 */ public String joining(CharSequence delimiter) { return collect(LongCollector.joining(delimiter)); }
/** * Returns a {@link String} which is the concatenation of the results of * calling {@link String#valueOf(long)} on each element of this stream, * separated by the specified delimiter, with the specified prefix and * suffix in encounter order. * * <p> * This is a terminal operation. * * @param delimiter the delimiter to be used between each element * @param prefix the sequence of characters to be used at the beginning of * the joined result * @param suffix the sequence of characters to be used at the end of the * joined result * @return the result of concatenation. For empty input stream * {@code prefix + suffix} is returned. * @since 0.3.1 */ public String joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix) { return collect(LongCollector.joining(delimiter, prefix, suffix)); }
/** * Returns the minimum element of this stream according to the provided key * extractor function. * * <p> * This is a terminal operation. * * @param keyExtractor a non-interfering, stateless function * @return an {@code OptionalLong} describing the first element of this * stream for which the lowest value was returned by key extractor, * or an empty {@code OptionalLong} if the stream is empty * @since 0.1.2 */ public OptionalLong minByLong(LongUnaryOperator keyExtractor) { long[] result = collect(() -> new long[3], (acc, l) -> { long key = keyExtractor.applyAsLong(l); if (acc[2] == 0 || acc[1] > key) { acc[0] = l; acc[1] = key; acc[2] = 1; } }, (acc1, acc2) -> { if (acc2[2] == 1 && (acc1[2] == 0 || acc1[1] > acc2[1])) System.arraycopy(acc2, 0, acc1, 0, 3); }); return result[2] == 1 ? OptionalLong.of(result[0]) : OptionalLong.empty(); }
/** * Returns the maximum element of this stream according to the provided key * extractor function. * * <p> * This is a terminal operation. * * @param keyExtractor a non-interfering, stateless function * @return an {@code OptionalLong} describing the first element of this * stream for which the highest value was returned by key extractor, * or an empty {@code OptionalLong} if the stream is empty * @since 0.1.2 */ public OptionalLong maxByDouble(LongToDoubleFunction keyExtractor) { return collect(PrimitiveBox::new, (box, l) -> { double key = keyExtractor.applyAsDouble(l); if (!box.b || Double.compare(box.d, key) < 0) { box.b = true; box.d = key; box.l = l; } }, PrimitiveBox.MAX_DOUBLE).asLong(); }
/** * Returns the maximum element of this stream according to the provided key * extractor function. * * <p> * This is a terminal operation. * * @param keyExtractor a non-interfering, stateless function * @return an {@code OptionalLong} describing the first element of this * stream for which the highest value was returned by key extractor, * or an empty {@code OptionalLong} if the stream is empty * @since 0.1.2 */ public OptionalLong maxByLong(LongUnaryOperator keyExtractor) { long[] result = collect(() -> new long[3], (acc, l) -> { long key = keyExtractor.applyAsLong(l); if (acc[2] == 0 || acc[1] < key) { acc[0] = l; acc[1] = key; acc[2] = 1; } }, (acc1, acc2) -> { if (acc2[2] == 1 && (acc1[2] == 0 || acc1[1] < acc2[1])) System.arraycopy(acc2, 0, acc1, 0, 3); }); return result[2] == 1 ? OptionalLong.of(result[0]) : OptionalLong.empty(); }
/** * Returns the minimum element of this stream according to the provided key * extractor function. * * <p> * This is a terminal operation. * * @param <V> the type of the {@code Comparable} sort key * @param keyExtractor a non-interfering, stateless function * @return an {@code OptionalLong} describing the first element of this * stream for which the lowest value was returned by key extractor, * or an empty {@code OptionalLong} if the stream is empty * @since 0.1.2 */ public <V extends Comparable<? super V>> OptionalLong minBy(LongFunction<V> keyExtractor) { ObjLongBox<V> result = collect(() -> new ObjLongBox<>(null, 0), (box, i) -> { V val = Objects.requireNonNull(keyExtractor.apply(i)); if (box.a == null || box.a.compareTo(val) > 0) { box.a = val; box.b = i; } }, (box1, box2) -> { if (box2.a != null && (box1.a == null || box1.a.compareTo(box2.a) > 0)) { box1.a = box2.a; box1.b = box2.b; } }); return result.a == null ? OptionalLong.empty() : OptionalLong.of(result.b); }
/** * Returns the minimum element of this stream according to the provided key * extractor function. * * <p> * This is a terminal operation. * * @param keyExtractor a non-interfering, stateless function * @return an {@code OptionalLong} describing the first element of this * stream for which the lowest value was returned by key extractor, * or an empty {@code OptionalLong} if the stream is empty * @since 0.1.2 */ public OptionalLong minByDouble(LongToDoubleFunction keyExtractor) { return collect(PrimitiveBox::new, (box, l) -> { double key = keyExtractor.applyAsDouble(l); if (!box.b || Double.compare(box.d, key) > 0) { box.b = true; box.d = key; box.l = l; } }, PrimitiveBox.MIN_DOUBLE).asLong(); }
/** * Returns the maximum element of this stream according to the provided key * extractor function. * * <p> * This is a terminal operation. * * @param <V> the type of the {@code Comparable} sort key * @param keyExtractor a non-interfering, stateless function * @return an {@code OptionalLong} describing the first element of this * stream for which the highest value was returned by key extractor, * or an empty {@code OptionalLong} if the stream is empty * @since 0.1.2 */ public <V extends Comparable<? super V>> OptionalLong maxBy(LongFunction<V> keyExtractor) { ObjLongBox<V> result = collect(() -> new ObjLongBox<>(null, 0), (box, i) -> { V val = Objects.requireNonNull(keyExtractor.apply(i)); if (box.a == null || box.a.compareTo(val) < 0) { box.a = val; box.b = i; } }, (box1, box2) -> { if (box2.a != null && (box1.a == null || box1.a.compareTo(box2.a) < 0)) { box1.a = box2.a; box1.b = box2.b; } }); return result.a == null ? OptionalLong.empty() : OptionalLong.of(result.b); }
/** * Returns the maximum element of this stream according to the provided key * extractor function. * * <p> * This is a terminal operation. * * @param keyExtractor a non-interfering, stateless function * @return an {@code OptionalLong} describing the first element of this * stream for which the highest value was returned by key extractor, * or an empty {@code OptionalLong} if the stream is empty * @since 0.1.2 */ public OptionalLong maxByInt(LongToIntFunction keyExtractor) { return collect(PrimitiveBox::new, (box, l) -> { int key = keyExtractor.applyAsInt(l); if (!box.b || box.i < key) { box.b = true; box.i = key; box.l = l; } }, PrimitiveBox.MAX_INT).asLong(); }
/** * Returns the minimum element of this stream according to the provided key * extractor function. * * <p> * This is a terminal operation. * * @param keyExtractor a non-interfering, stateless function * @return an {@code OptionalLong} describing the first element of this * stream for which the lowest value was returned by key extractor, * or an empty {@code OptionalLong} if the stream is empty * @since 0.1.2 */ public OptionalLong minByInt(LongToIntFunction keyExtractor) { return collect(PrimitiveBox::new, (box, l) -> { int key = keyExtractor.applyAsInt(l); if (!box.b || box.i > key) { box.b = true; box.i = key; box.l = l; } }, PrimitiveBox.MIN_INT).asLong(); }
/** * Performs a mutable reduction operation on the elements of this stream * using an {@link LongCollector} which encapsulates the supplier, * accumulator and merger functions making easier to reuse collection * strategies. * * <p> * Like {@link #reduce(long, LongBinaryOperator)}, {@code collect} * operations can be parallelized without requiring additional * synchronization. * * <p> * This is a terminal operation. * * @param <A> the intermediate accumulation type of the * {@code LongCollector} * @param <R> type of the result * @param collector the {@code LongCollector} describing the reduction * @return the result of the reduction * @see #collect(Supplier, ObjLongConsumer, BiConsumer) * @since 0.3.0 */ @SuppressWarnings("unchecked") public <A, R> R collect(LongCollector<A, R> collector) { if (collector.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) return (R) collect(collector.supplier(), collector.longAccumulator(), collector.merger()); return collector.finisher().apply(collect(collector.supplier(), collector.longAccumulator(), collector .merger())); }