java.util.stream.Collector.Characteristics Java Examples
The following examples show how to use
java.util.stream.Collector.Characteristics.
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 |
@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: JsLibraryDescriptionTest.java From buck with Apache License 2.0 | 6 votes |
private static <T> Collector<T, AtomicLong, Long> countAssertions(Consumer<T> assertion) { /** * Collects a stream by running the passed-in assertion on all stream items. The collection also * asserts that the stream is non-empty, to avoid false positives when accidentally producing * empty streams, e.g. by filtering. */ return Collector.of( AtomicLong::new, (count, t) -> { count.incrementAndGet(); assertion.accept(t); }, (a, b) -> new AtomicLong(a.get() + b.get()), count -> { long value = count.get(); if (value == 0) { throw new IllegalStateException("Stream was empty, did not assert anything."); } return value; }, Characteristics.UNORDERED); }
Example #3
Source File: StreamEx.java From streamex with Apache License 2.0 | 6 votes |
/** * Perform a partial mutable reduction using the supplied {@link Collector} * on a series of adjacent elements. * * <p> * This is a <a href="package-summary.html#StreamOps">quasi-intermediate</a> * partial reduction operation. * * @param <R> the type of the elements in the resulting stream * @param <A> the intermediate accumulation type of the {@code Collector} * @param collapsible a non-interfering, stateless predicate to apply to the * pair of adjacent elements of the input stream which returns true * for elements which should be collected together. * @param collector a {@code Collector} which is used to combine the * adjacent elements. * @return the new stream * @since 0.3.6 */ public <R, A> StreamEx<R> collapse(BiPredicate<? super T, ? super T> collapsible, Collector<? super T, A, R> collector) { Supplier<A> supplier = collector.supplier(); BiConsumer<A, ? super T> accumulator = collector.accumulator(); StreamEx<A> stream = collapseInternal(collapsible, t -> { A acc = supplier.get(); accumulator.accept(acc, t); return acc; }, (acc, t) -> { accumulator.accept(acc, t); return acc; }, collector.combiner()); if (collector.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) { @SuppressWarnings("unchecked") StreamEx<R> result = (StreamEx<R>) stream; return result; } return stream.map(collector.finisher()); }
Example #4
Source File: MoreCollectors.java From arctic-sea with Apache License 2.0 | 5 votes |
public static <X> Collector<X, ?, Set<X>> toDuplicateSet(int min) { if (min < 2) { throw new IllegalArgumentException(); } Supplier<Map<X, Integer>> supplier = HashMap::new; BiConsumer<Map<X, Integer>, X> accumulator = (map, key) -> map.merge(key, 1, Integer::sum); BinaryOperator<Map<X, Integer>> combiner = Functions.mergeToLeftMap(Integer::sum); Function<Map<X, Integer>, Set<X>> finisher = Functions.keySetWhereValues(v -> v >= min); return Collector.of(supplier, accumulator, combiner, finisher, Characteristics.UNORDERED); }
Example #5
Source File: MoreCollectors.java From arctic-sea with Apache License 2.0 | 5 votes |
public static <X> Collector<X, ?, Stream<X>> toDuplicateStream(int min) { if (min < 2) { throw new IllegalArgumentException(); } Supplier<Map<X, Integer>> supplier = HashMap::new; BiConsumer<Map<X, Integer>, X> accumulator = (map, key) -> map.merge(key, 1, Integer::sum); BinaryOperator<Map<X, Integer>> combiner = Functions.mergeToLeftMap(Integer::sum); Function<Map<X, Integer>, Stream<X>> finisher = Functions.keyStreamWhereValues(v -> v >= min); return Collector.of(supplier, accumulator, combiner, finisher, Characteristics.UNORDERED); }
Example #6
Source File: MoreCollectors.java From arctic-sea with Apache License 2.0 | 5 votes |
public static <T> Collector<T, ?, T> toSingleResult(Supplier<? extends RuntimeException> exceptionSupplier) { Objects.requireNonNull(exceptionSupplier); Supplier<List<T>> supplier = LinkedList<T>::new; BiConsumer<List<T>, T> accumulator = List<T>::add; BinaryOperator<List<T>> combiner = Functions.mergeLeft(List::addAll); Function<List<T>, T> finisher = list -> { if (list.size() != 1) { throw exceptionSupplier.get(); } return list.get(0); }; return Collector.of(supplier, accumulator, combiner, finisher, Characteristics.UNORDERED); }
Example #7
Source File: NbtUtils.java From WearableBackpacks with MIT License | 5 votes |
/** Returns a collector that accumulates the the input NBT tags into a new NBT list. */ public static <T> Collector<T, NBTTagCompound, NBTTagCompound> toCompound( Function<T, String> keyMapper, Function<T, NBTBase> tagMapper) { return Collector.of(NBTTagCompound::new, (compound, element) -> compound.setTag(keyMapper.apply(element), tagMapper.apply(element)), (left, right) -> { for (String key : right.getKeySet()) left.setTag(key, right.getTag(key)); return left; }, Characteristics.IDENTITY_FINISH); }
Example #8
Source File: NbtUtils.java From WearableBackpacks with MIT License | 5 votes |
/** Returns a collector that accumulates the the input elements into a new NBT list. */ public static <T> Collector<T, NBTTagList, NBTTagList> toList() { return Collector.of(NBTTagList::new, (list, element) -> list.appendTag(createTag(element)), (left, right) -> { for (NBTBase tag : iterate(right)) left.appendTag(tag); return left; }, Characteristics.IDENTITY_FINISH); }
Example #9
Source File: MoreCollectorsTest.java From streamex with Apache License 2.0 | 5 votes |
@Test public void testIfAllMatch() { assertThrows(NullPointerException.class, () -> MoreCollectors.ifAllMatch(null, Collectors.toList())); assertThrows(NullPointerException.class, () -> MoreCollectors.ifAllMatch(i -> true, null)); assertFalse(MoreCollectors.ifAllMatch(i -> true, Collectors.toList()).characteristics() .contains(Characteristics.UNORDERED)); assertTrue(MoreCollectors.ifAllMatch(i -> true, Collectors.toSet()).characteristics() .contains(Characteristics.UNORDERED)); Supplier<Stream<Integer>> five = () -> IntStreamEx.range(5).boxed(); checkShortCircuitCollector("ifAllMatch: all match", Optional.of(asList(0, 1, 2, 3, 4)), 5, five, MoreCollectors.ifAllMatch(i -> true, Collectors.toList())); Supplier<Stream<Integer>> ints = () -> IntStreamEx.ints().boxed(); checkShortCircuitCollector("ifAllMatch: shirtCircuit downstream", Optional.of(asList(0, 1, 2)), 3, ints, MoreCollectors.ifAllMatch(i -> true, MoreCollectors.head(3)), true); checkShortCircuitCollector("ifAllMatch: shirtCircuit downstream", Optional.empty(), 4, ints, MoreCollectors.ifAllMatch(i -> i < 3, MoreCollectors.head(5)), true); checkShortCircuitCollector("ifAllMatch: some match", Optional.empty(), 11, ints, MoreCollectors.ifAllMatch(i -> i < 10, Collectors.toList()), true); checkShortCircuitCollector("ifAllMatch: some match", Optional.empty(), 2, five, MoreCollectors.ifAllMatch(i -> i % 2 == 0, Collectors.toList())); checkShortCircuitCollector("ifAllMatch: empty stream", Optional.of(Collections.emptyList()), 0, Stream::empty, MoreCollectors.ifAllMatch(i -> true, Collectors.toList())); }
Example #10
Source File: MoreCollectors.java From streamex with Apache License 2.0 | 5 votes |
/** * 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 #11
Source File: AbstractStreamEx.java From streamex with Apache License 2.0 | 5 votes |
/** * {@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 #12
Source File: Internals.java From streamex with Apache License 2.0 | 5 votes |
BaseCollector(Supplier<A> supplier, BiConsumer<A, A> merger, Function<A, R> finisher, Set<Characteristics> characteristics) { this.supplier = supplier; this.merger = merger; this.finisher = finisher; this.characteristics = characteristics; }
Example #13
Source File: BiStream.java From mug with Apache License 2.0 | 5 votes |
static <T, E, A, R> Collector<T, A, R> flatMapping( Function<? super T, ? extends Stream<? extends E>> mapper, Collector<E, A, R> collector) { BiConsumer<A, E> accumulator = collector.accumulator(); return Collector.of( collector.supplier(), (a, input) -> mapper.apply(input).forEachOrdered(e -> accumulator.accept(a, e)), collector.combiner(), collector.finisher(), collector.characteristics().toArray(new Characteristics[0])); }
Example #14
Source File: Internals.java From streamex with Apache License 2.0 | 5 votes |
CancellableCollectorImpl(Supplier<A> supplier, BiConsumer<A, T> accumulator, BinaryOperator<A> combiner, Function<A, R> finisher, Predicate<A> finished, Set<java.util.stream.Collector.Characteristics> characteristics) { this.supplier = supplier; this.accumulator = accumulator; this.combiner = combiner; this.finisher = finisher; this.finished = finished; this.characteristics = characteristics; }
Example #15
Source File: Internals.java From streamex with Apache License 2.0 | 4 votes |
@Override public Set<Characteristics> characteristics() { return characteristics; }
Example #16
Source File: Internals.java From streamex with Apache License 2.0 | 4 votes |
DoubleCollectorImpl(Supplier<A> supplier, ObjDoubleConsumer<A> doubleAccumulator, BiConsumer<A, A> merger, Function<A, R> finisher, Set<Characteristics> characteristics) { super(supplier, merger, finisher, characteristics); this.doubleAccumulator = doubleAccumulator; }
Example #17
Source File: Internals.java From streamex with Apache License 2.0 | 4 votes |
LongCollectorImpl(Supplier<A> supplier, ObjLongConsumer<A> longAccumulator, BiConsumer<A, A> merger, Function<A, R> finisher, Set<Characteristics> characteristics) { super(supplier, merger, finisher, characteristics); this.longAccumulator = longAccumulator; }
Example #18
Source File: Internals.java From streamex with Apache License 2.0 | 4 votes |
IntCollectorImpl(Supplier<A> supplier, ObjIntConsumer<A> intAccumulator, BiConsumer<A, A> merger, Function<A, R> finisher, Set<Characteristics> characteristics) { super(supplier, merger, finisher, characteristics); this.intAccumulator = intAccumulator; }
Example #19
Source File: CookieStoreCollectorTests.java From vividus with Apache License 2.0 | 4 votes |
@Test void testCharacteristics() { Set<Characteristics> characteristics = cookieStoreCollector.characteristics(); assertEquals(characteristics, EnumSet.of(Characteristics.UNORDERED, Characteristics.IDENTITY_FINISH)); }
Example #20
Source File: Internals.java From streamex with Apache License 2.0 | 4 votes |
<T> Collector<T, A, R> asRef(BiConsumer<A, T> accumulator) { return Collector.of(supplier, accumulator, combiner(), finisher, characteristics .toArray(new Characteristics[0])); }
Example #21
Source File: Internals.java From streamex with Apache License 2.0 | 4 votes |
PartialCollector(Supplier<A> supplier, BiConsumer<A, A> merger, Function<A, R> finisher, Set<Characteristics> characteristics) { super(supplier, merger, finisher, characteristics); }
Example #22
Source File: Internals.java From streamex with Apache License 2.0 | 4 votes |
@Override public Set<Characteristics> characteristics() { return characteristics; }
Example #23
Source File: MoreCollectors.java From arctic-sea with Apache License 2.0 | 4 votes |
private static <T, A, R> Characteristics[] getCharacteristics(Collector<T, A, R> downstream) { return downstream.characteristics().stream().toArray(Characteristics[]::new); }
Example #24
Source File: MoreCollectors.java From streamex with Apache License 2.0 | 3 votes |
/** * Returns a {@code Collector} which just ignores the input and calls the * provided supplier once to return the output. * * @param <T> the type of input elements * @param <U> the type of output * @param supplier the supplier of the output * @return a {@code Collector} which just ignores the input and calls the * provided supplier once to return the output. */ private static <T, U> Collector<T, ?, U> empty(Supplier<U> supplier) { return new CancellableCollectorImpl<>(() -> NONE, (acc, t) -> { // empty }, selectFirst(), acc -> supplier.get(), alwaysTrue(), EnumSet.of(Characteristics.UNORDERED, Characteristics.CONCURRENT)); }
Example #25
Source File: MoreCollectors.java From streamex with Apache License 2.0 | 3 votes |
/** * 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 #26
Source File: Collectors2.java From super-cloudops with Apache License 2.0 | 3 votes |
/** * Returns a {@code Collector} that accumulates the input elements into a * new {@code Set}. There are no guarantees on the type, mutability, * serializability, or thread-safety of the {@code Set} returned; if more * control over the returned {@code Set} is required, use * {@link Collectors#toCollection(Supplier)}. * * <p> * This is an {@link Collector.Characteristics#UNORDERED unordered} * Collector. * * @param <T> * the type of the input elements * @return a {@code Collector} which collects all the input elements into a * {@code Set} */ @SuppressWarnings("unchecked") public static <T> Collector<T, ?, Set<T>> toLinkedHashSet() { return Collector.of(LinkedHashSet::new, Set::add, (s, rs) -> { s.add((T) rs); return s; }, Characteristics.IDENTITY_FINISH); }
Example #27
Source File: MoreCollectors.java From streamex with Apache License 2.0 | 3 votes |
/** * 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); }
Example #28
Source File: EntryStream.java From streamex with Apache License 2.0 | 3 votes |
/** * Returns a {@link Map} where elements of this stream with the same key are * grouped together. The resulting {@code Map} keys are the keys of this * stream entries and the corresponding values are combined using the * provided downstream collector. * * <p> * There are no guarantees on the type, mutability, serializability, or * thread-safety of the {@code Map} object returned. If more control over * the returned {@code Map} is required, use * {@link #grouping(Supplier, Collector)}. * * <p> * This is a <a href="package-summary.html#StreamOps">terminal</a> * operation. * * @param <A> the intermediate accumulation type of the downstream collector * @param <D> the result type of the downstream reduction * @param downstream a {@code Collector} implementing the downstream * reduction * @return a {@code Map} containing the elements of this stream * @see Collectors#groupingBy(Function, Collector) */ public <A, D> Map<K, D> grouping(Collector<? super V, A, D> downstream) { Function<Entry<K, V>, K> keyMapper = Entry::getKey; Collector<Entry<K, V>, ?, D> mapping = Collectors.mapping(Entry::getValue, downstream); if (isParallel() && downstream.characteristics().contains(Characteristics.UNORDERED)) { return collect(Collectors.groupingByConcurrent(keyMapper, mapping)); } return collect(Collectors.groupingBy(keyMapper, mapping)); }
Example #29
Source File: EntryStream.java From streamex with Apache License 2.0 | 3 votes |
/** * Returns a {@link Map} where elements of this stream with the same key are * grouped together. The resulting {@code Map} keys are the keys of this * stream entries and the corresponding values are combined using the * provided downstream collector. The {@code Map} is created using * the provided supplier function. * * <p> * This is a <a href="package-summary.html#StreamOps">terminal</a> * operation. * * @param <A> the intermediate accumulation type of the downstream collector * @param <D> the result type of the downstream reduction * @param <M> the type of the resulting {@code Map} * @param mapSupplier a function which returns a new, empty {@code Map} into * which the results will be inserted * @param downstream a {@code Collector} implementing the downstream * reduction * @return a {@code Map} containing the elements of this stream * @see Collectors#groupingBy(Function, Supplier, Collector) */ @SuppressWarnings("unchecked") public <A, D, M extends Map<K, D>> M grouping(Supplier<M> mapSupplier, Collector<? super V, A, D> downstream) { Function<Entry<K, V>, K> keyMapper = Entry::getKey; Collector<Entry<K, V>, ?, D> mapping = Collectors.mapping(Entry::getValue, downstream); if (isParallel() && downstream.characteristics().contains(Characteristics.UNORDERED) && mapSupplier.get() instanceof ConcurrentMap) { return (M) collect(Collectors.groupingByConcurrent(keyMapper, (Supplier<? extends ConcurrentMap<K, D>>) mapSupplier, mapping)); } return collect(Collectors.groupingBy(keyMapper, mapSupplier, mapping)); }
Example #30
Source File: StreamEx.java From streamex with Apache License 2.0 | 3 votes |
/** * Returns a {@code Map} whose keys are the values resulting from applying * the classification function to the input elements, and whose * corresponding values are the result of reduction of the input elements * which map to the associated key under the classification function. * * <p> * The {@code Map} will be created using the provided factory function. * * <p> * This is a <a href="package-summary.html#StreamOps">terminal</a> * operation. * * @param <K> the type of the keys * @param <D> the result type of the downstream reduction * @param <M> the type of the resulting {@code Map} * @param classifier the classifier function mapping input elements to keys * @param mapFactory a function which, when called, produces a new empty * {@code Map} of the desired type * @param downstream a {@code Collector} implementing the downstream * reduction * @return a {@code Map} containing the results of the group-by operation * * @see #groupingBy(Function) * @see Collectors#groupingBy(Function, Supplier, Collector) * @see Collectors#groupingByConcurrent(Function, Supplier, Collector) */ @SuppressWarnings("unchecked") public <K, D, M extends Map<K, D>> M groupingBy(Function<? super T, ? extends K> classifier, Supplier<M> mapFactory, Collector<? super T, ?, D> downstream) { if (isParallel() && downstream.characteristics().contains(Characteristics.UNORDERED) && mapFactory.get() instanceof ConcurrentMap) return (M) rawCollect(Collectors.groupingByConcurrent(classifier, (Supplier<ConcurrentMap<K, D>>) mapFactory, downstream)); return rawCollect(Collectors.groupingBy(classifier, mapFactory, downstream)); }