use of java.util.stream.Collector.Characteristics 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 java.util.stream.Collector.Characteristics in project sandbox by backpaper0.
the class ScanCollectorTest method scan.
/**
* <tt>[t<sub>0</sub>, t<sub>1</sub>, t<sub>2</sub> ... t<sub>n</sub>]</tt>というストリームに対して
* <pre>
* r<sub>0</sub> = init
* r<sub>1</sub> = fn(r<sub>0</sub>, t<sub>0</sub>)
* r<sub>2</sub> = fn(r<sub>1</sub>, t<sub>1</sub>)
* r<sub>3</sub> = fn(r<sub>2</sub>, t<sub>2</sub>)
* .
* .
* .
* r<sub>n+1</sub> = fn(r<sub>n</sub>, t<sub>n</sub>)
* </pre>
* と処理して<tt>[r<sub>0</sub>, r<sub>1</sub>, r<sub>2</sub> ... r<sub>n+1</sub>]</tt>というリストを返します。
*
* @param init
* @param fn
* @return
*/
static <T, R> Collector<T, ?, List<R>> scan(final R init, final BiFunction<R, T, R> fn) {
final Supplier<LinkedList<R>> supplier = () -> new LinkedList<>(Collections.singletonList(init));
final BiConsumer<LinkedList<R>, T> accumulator = (acc, t) -> acc.add(fn.apply(acc.getLast(), t));
final BinaryOperator<LinkedList<R>> combiner = (acc1, acc2) -> {
acc1.addAll(acc2);
return acc1;
};
final Function<LinkedList<R>, List<R>> finisher = acc -> acc;
final Characteristics characteristics = Characteristics.IDENTITY_FINISH;
return Collector.of(supplier, accumulator, combiner, finisher, characteristics);
}
Aggregations