Java Code Examples for java.util.stream.Collector#combiner()

The following examples show how to use java.util.stream.Collector#combiner() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: Internals.java    From streamex with Apache License 2.0 6 votes vote down vote up
@SuppressWarnings("unchecked")
static <K, D, A, M extends Map<K, D>> PartialCollector<Map<K, A>, M> grouping(Supplier<M> mapFactory,
        Collector<?, A, D> downstream) {
    BinaryOperator<A> downstreamMerger = downstream.combiner();
    BiConsumer<Map<K, A>, Map<K, A>> merger = (map1, map2) -> {
        for (Map.Entry<K, A> e : map2.entrySet())
            map1.merge(e.getKey(), e.getValue(), downstreamMerger);
    };

    if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
        return (PartialCollector<Map<K, A>, M>) new PartialCollector<>((Supplier<Map<K, A>>) mapFactory,
                merger, Function.identity(), ID_CHARACTERISTICS);
    }
    Function<A, D> downstreamFinisher = downstream.finisher();
    return new PartialCollector<>((Supplier<Map<K, A>>) mapFactory, merger, map -> {
        map.replaceAll((k, v) -> ((Function<A, A>) downstreamFinisher).apply(v));
        return (M) map;
    }, NO_CHARACTERISTICS);
}
 
Example 2
Source File: AbstractStreamEx.java    From streamex with Apache License 2.0 5 votes vote down vote up
/**
 * {@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);
}
 
Example 3
Source File: Internals.java    From streamex with Apache License 2.0 5 votes vote down vote up
static <A, R> PartialCollector<Box<A>, R> partialCollector(Collector<?, A, R> c) {
    Supplier<A> supplier = c.supplier();
    BinaryOperator<A> combiner = c.combiner();
    Function<A, R> finisher = c.finisher();
    return new PartialCollector<>(() -> new Box<>(supplier.get()), (box1, box2) -> box1.a = combiner.apply(
        box1.a, box2.a), box -> finisher.apply(box.a), NO_CHARACTERISTICS);
}
 
Example 4
Source File: MoreCollectors.java    From streamex with Apache License 2.0 5 votes vote down vote up
/**
 * 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]));
}
 
Example 5
Source File: EntryStream.java    From streamex with Apache License 2.0 4 votes vote down vote up
/**
 * Merge series of adjacent stream entries with equal keys combining the
 * corresponding values using the provided {@code Collector}.
 *
 * <p>
 * This is a <a href="package-summary.html#StreamOps">quasi-intermediate</a>
 * partial reduction operation.
 *
 * <p>
 * The key of the resulting entry is the key of the first merged entry.
 *
 * @param <R> the type of the values in the resulting stream
 * @param <A> the intermediate accumulation type of the {@code Collector}
 * @param collector a {@code Collector} which is used to combine the values
 *        of the adjacent entries with the equal keys.
 * @return a new {@code EntryStream} which keys are the keys of the original
 *         stream and the values are values of the adjacent entries with the
 *         same keys, combined using the provided collector.
 * @see StreamEx#collapse(BiPredicate, Collector)
 * @since 0.5.5
 */
public <A, R> EntryStream<K, R> collapseKeys(Collector<? super V, A, R> collector) {
    Supplier<A> supplier = collector.supplier();
    BiConsumer<A, ? super V> accumulator = collector.accumulator();
    BinaryOperator<A> combiner = collector.combiner();
    Function<A, R> finisher = collector.finisher();
    return new StreamEx<>(new CollapseSpliterator<>(equalKeys(), e -> {
        A a = supplier.get();
        accumulator.accept(a, e.getValue());
        return new PairBox<>(e.getKey(), a);
    }, (pb, e) -> {
        accumulator.accept(pb.b, e.getValue());
        return pb;
    }, (pb1, pb2) -> {
        pb1.b = combiner.apply(pb1.b, pb2.b);
        return pb1;
    }, spliterator()), context).mapToEntry(pb -> pb.a, pb -> finisher.apply(pb.b));
}
 
Example 6
Source File: MoreCollectors.java    From streamex with Apache License 2.0 3 votes vote down vote up
/**
 * Adapts a {@code Collector} to perform an additional finishing
 * transformation.
 * 
 * <p>
 * Unlike {@link Collectors#collectingAndThen(Collector, Function)} this
 * method returns a
 * <a href="package-summary.html#ShortCircuitReduction">short-circuiting
 * collector</a> if the downstream collector is short-circuiting.
 *
 * @param <T> the type of the input elements
 * @param <A> intermediate accumulation type of the downstream collector
 * @param <R> result type of the downstream collector
 * @param <RR> result type of the resulting collector
 * @param downstream a collector
 * @param finisher a function to be applied to the final result of the
 *        downstream collector
 * @return a collector which performs the action of the downstream
 *         collector, followed by an additional finishing step
 * @throws NullPointerException if downstream is null, or finisher is null.
 * @see Collectors#collectingAndThen(Collector, Function)
 * @since 0.4.0
 */
public static <T, A, R, RR> Collector<T, A, RR> collectingAndThen(Collector<T, A, R> downstream,
        Function<R, RR> finisher) {
    Predicate<A> finished = finished(downstream);
    if (finished != null) {
        return new CancellableCollectorImpl<>(downstream.supplier(), downstream.accumulator(), downstream
                .combiner(), downstream.finisher().andThen(finisher), finished, downstream.characteristics()
                        .contains(Characteristics.UNORDERED) ? UNORDERED_CHARACTERISTICS : NO_CHARACTERISTICS);
    }
    return Collectors.collectingAndThen(downstream, finisher);
}
 
Example 7
Source File: MoreCollectors.java    From streamex with Apache License 2.0 3 votes vote down vote up
/**
 * Adapts a {@code Collector} accepting elements of type {@code U} to one
 * accepting elements of type {@code T} by applying a mapping function to
 * each input element before accumulation.
 *
 * <p>
 * Unlike {@link Collectors#mapping(Function, Collector)} this method
 * returns a
 * <a href="package-summary.html#ShortCircuitReduction">short-circuiting
 * collector</a> if the downstream collector is short-circuiting.
 * 
 * @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
 * @param downstream a collector which will accept mapped values
 * @return a collector which applies the mapping function to the input
 *         elements and provides the mapped results to the downstream
 *         collector
 * @throws NullPointerException if mapper is null, or downstream is null.
 * @see Collectors#mapping(Function, Collector)
 * @since 0.4.0
 */
public static <T, U, A, R> Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper,
        Collector<? super U, A, R> downstream) {
    Objects.requireNonNull(mapper);
    Predicate<A> finished = finished(downstream);
    if (finished != null) {
        BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
        return new CancellableCollectorImpl<>(downstream.supplier(), (acc, t) -> {
            if (!finished.test(acc))
                downstreamAccumulator.accept(acc, mapper.apply(t));
        }, downstream.combiner(), downstream.finisher(), finished, downstream.characteristics());
    }
    return Collectors.mapping(mapper, downstream);
}
 
Example 8
Source File: MoreCollectors.java    From streamex with Apache License 2.0 3 votes vote down vote up
/**
 * Returns a {@code Collector} which performs downstream reduction if all
 * elements satisfy the {@code Predicate}. The result is described as an
 * {@code Optional<R>}.
 * 
 * <p>
 * The resulting collector returns an empty optional if at least one input
 * element does not satisfy the predicate. Otherwise it returns an optional
 * which contains the result of the downstream collector.
 * 
 * <p>
 * This method returns a
 * <a href="package-summary.html#ShortCircuitReduction">short-circuiting
 * collector</a>: it may not process all the elements if some of items don't
 * satisfy the predicate or if downstream collector is a short-circuiting
 * collector.
 * 
 * <p>
 * It's guaranteed that the downstream collector is not called for elements
 * which don't satisfy the predicate.
 *
 * @param <T> the type of input elements
 * @param <A> intermediate accumulation type of the downstream collector
 * @param <R> result type of the downstream collector
 * @param predicate a non-interfering, stateless predicate to checks whether
 *        collector should proceed with element
 * @param downstream a {@code Collector} implementing the downstream
 *        reduction
 * @return a {@code Collector} witch performs downstream reduction if all
 *         elements satisfy the predicate
 * @throws NullPointerException if mapper is null.
 * @see Stream#allMatch(Predicate)
 * @see AbstractStreamEx#dropWhile(Predicate)
 * @see AbstractStreamEx#takeWhile(Predicate)
 * @since 0.6.3
 */
public static <T, A, R> Collector<T, ?, Optional<R>> ifAllMatch(Predicate<T> predicate,
        Collector<T, A, R> downstream) {
    Objects.requireNonNull(predicate);
    Predicate<A> finished = finished(downstream);
    Supplier<A> supplier = downstream.supplier();
    BiConsumer<A, T> accumulator = downstream.accumulator();
    BinaryOperator<A> combiner = downstream.combiner();
    return new CancellableCollectorImpl<>(
            () -> new PairBox<>(supplier.get(), Boolean.TRUE),
            (acc, t) -> {
                if (acc.b && predicate.test(t)) {
                    accumulator.accept(acc.a, t);
                } else {
                    acc.b = Boolean.FALSE;
                }
            },
            (acc1, acc2) -> {
                if (acc1.b && acc2.b) {
                    acc1.a = combiner.apply(acc1.a, acc2.a);
                } else {
                    acc1.b = Boolean.FALSE;
                }
                return acc1;
            },
            acc -> acc.b ? Optional.of(downstream.finisher().apply(acc.a)) : Optional.empty(),
            finished == null ? acc -> !acc.b : acc -> !acc.b || finished.test(acc.a),
            downstream.characteristics().contains(Characteristics.UNORDERED) ? UNORDERED_CHARACTERISTICS
                    : NO_CHARACTERISTICS);
}