Search in sources :

Example 1 with CancelException

use of one.util.streamex.Internals.CancelException in project streamex by amaembo.

the class MoreCollectors method flatMapping.

/**
 * Adapts a {@code Collector} accepting elements of type {@code U} to one
 * accepting elements of type {@code T} by applying a flat mapping function
 * to each input element before accumulation. The flat mapping function maps
 * an input element to a {@link Stream stream} covering zero or more output
 * elements that are then accumulated downstream. Each mapped stream is
 * {@link java.util.stream.BaseStream#close() closed} after its contents
 * have been placed downstream. (If a mapped stream is {@code null} an empty
 * stream is used, instead.)
 *
 * <p>
 * This method is similar to {@code Collectors.flatMapping} method which
 * appears in JDK 9. However when downstream collector is
 * <a href="package-summary.html#ShortCircuitReduction">short-circuiting</a>
 * , this method will also return a short-circuiting collector.
 *
 * @param <T> the type of the input elements
 * @param <U> type of elements accepted by downstream collector
 * @param <A> intermediate accumulation type of the downstream collector
 * @param <R> result type of collector
 * @param mapper a function to be applied to the input elements, which
 *        returns a stream of results
 * @param downstream a collector which will receive the elements of the
 *        stream returned by mapper
 * @return a collector which applies the mapping function to the input
 *         elements and provides the flat mapped results to the downstream
 *         collector
 * @throws NullPointerException if mapper is null, or downstream is null.
 * @since 0.4.1
 */
public static <T, U, A, R> Collector<T, ?, R> flatMapping(Function<? super T, ? extends Stream<? extends U>> mapper, Collector<? super U, A, R> downstream) {
    Objects.requireNonNull(mapper);
    BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
    Predicate<A> finished = finished(downstream);
    if (finished != null) {
        return new CancellableCollectorImpl<>(downstream.supplier(), (acc, t) -> {
            if (finished.test(acc))
                return;
            try (Stream<? extends U> stream = mapper.apply(t)) {
                if (stream != null) {
                    stream.spliterator().forEachRemaining(u -> {
                        downstreamAccumulator.accept(acc, u);
                        if (finished.test(acc))
                            throw new CancelException();
                    });
                }
            } catch (CancelException ex) {
            // ignore
            }
        }, downstream.combiner(), downstream.finisher(), finished, downstream.characteristics());
    }
    return Collector.of(downstream.supplier(), (acc, t) -> {
        try (Stream<? extends U> stream = mapper.apply(t)) {
            if (stream != null) {
                stream.spliterator().forEachRemaining(u -> downstreamAccumulator.accept(acc, u));
            }
        }
    }, downstream.combiner(), downstream.finisher(), downstream.characteristics().toArray(new Characteristics[0]));
}
Also used : Characteristics(java.util.stream.Collector.Characteristics) CancelException(one.util.streamex.Internals.CancelException) CancellableCollectorImpl(one.util.streamex.Internals.CancellableCollectorImpl)

Example 2 with CancelException

use of one.util.streamex.Internals.CancelException in project streamex by amaembo.

the class UnorderedCancellableSpliterator method tryAdvance.

@Override
public boolean tryAdvance(Consumer<? super A> action) {
    Spliterator<T> source = this.source;
    if (source == null || cancelled.get()) {
        this.source = null;
        return false;
    }
    A acc = supplier.get();
    if (checkCancel(acc))
        return handleCancel(action, acc);
    try {
        source.forEachRemaining(t -> {
            accumulator.accept(acc, t);
            if (checkCancel(acc))
                throw new CancelException();
        });
    } catch (CancelException ex) {
        return handleCancel(action, acc);
    }
    A result = acc;
    while (true) {
        A acc2 = partialResults.poll();
        if (acc2 == null)
            break;
        result = combiner.apply(result, acc2);
        if (checkCancel(result))
            return handleCancel(action, result);
    }
    partialResults.offer(result);
    this.source = null;
    if (nPeers.decrementAndGet() == 0) {
        result = partialResults.poll();
        // non-cancelled finish
        while (true) {
            A acc2 = partialResults.poll();
            if (acc2 == null)
                break;
            result = combiner.apply(result, acc2);
            if (cancelPredicate.test(result))
                break;
        }
        this.source = null;
        action.accept(result);
        return true;
    }
    return false;
}
Also used : CancelException(one.util.streamex.Internals.CancelException)

Example 3 with CancelException

use of one.util.streamex.Internals.CancelException in project streamex by amaembo.

the class AbstractStreamEx method collect.

/**
 * {@inheritDoc}
 *
 * <p>
 * If special <a
 * href="package-summary.html#ShortCircuitReduction">short-circuiting
 * collector</a> is passed, this operation becomes short-circuiting as well.
 */
@Override
public <R, A> R collect(Collector<? super T, A, R> collector) {
    Predicate<A> finished = finished(collector);
    if (finished != null) {
        BiConsumer<A, ? super T> acc = collector.accumulator();
        BinaryOperator<A> combiner = collector.combiner();
        Spliterator<T> spliterator = spliterator();
        if (!isParallel()) {
            A a = collector.supplier().get();
            if (!finished.test(a)) {
                try {
                    // forEachRemaining can be much faster
                    // and take much less memory than tryAdvance for certain
                    // spliterators
                    spliterator.forEachRemaining(e -> {
                        acc.accept(a, e);
                        if (finished.test(a))
                            throw new CancelException();
                    });
                } catch (CancelException ex) {
                // ignore
                }
            }
            return collector.finisher().apply(a);
        }
        Spliterator<A> spltr;
        if (!spliterator.hasCharacteristics(Spliterator.ORDERED) || collector.characteristics().contains(Characteristics.UNORDERED)) {
            spltr = new UnorderedCancellableSpliterator<>(spliterator, collector.supplier(), acc, combiner, finished);
        } else {
            spltr = new OrderedCancellableSpliterator<>(spliterator, collector.supplier(), acc, combiner, finished);
        }
        return collector.finisher().apply(new StreamEx<>(StreamSupport.stream(spltr, true), context).findFirst().get());
    }
    return rawCollect(collector);
}
Also used : IMMUTABLE_TO_LIST(one.util.streamex.Internals.IMMUTABLE_TO_LIST) CancelException(one.util.streamex.Internals.CancelException)

Aggregations

CancelException (one.util.streamex.Internals.CancelException)3 Characteristics (java.util.stream.Collector.Characteristics)1 CancellableCollectorImpl (one.util.streamex.Internals.CancellableCollectorImpl)1 IMMUTABLE_TO_LIST (one.util.streamex.Internals.IMMUTABLE_TO_LIST)1