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]));
}
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;
}
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);
}
Aggregations