28 import java.util.AbstractSet;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.Comparator;
33 import java.util.DoubleSummaryStatistics;
34 import java.util.EnumSet;
35 import java.util.HashMap;
36 import java.util.HashSet;
37 import java.util.IntSummaryStatistics;
38 import java.util.Iterator;
39 import java.util.List;
40 import java.util.LongSummaryStatistics;
41 import java.util.Map;
42 import java.util.Objects;
43 import java.util.Optional;
44 import java.util.Set;
45 import java.util.StringJoiner;
46 import java.util.concurrent.ConcurrentHashMap;
47 import java.util.concurrent.ConcurrentMap;
48 import java.util.function.BiConsumer;
49 import java.util.function.BiFunction;
50 import java.util.function.BinaryOperator;
51 import java.util.function.Consumer;
52 import java.util.function.Function;
53 import java.util.function.Predicate;
54 import java.util.function.Supplier;
55 import java.util.function.ToDoubleFunction;
56 import java.util.function.ToIntFunction;
57 import java.util.function.ToLongFunction;
58
59 /**
60 * Implementations of {@link Collector} that implement various useful reduction
61 * operations, such as accumulating elements into collections, summarizing
62 * elements according to various criteria, etc.
63 *
64 * <p>The following are examples of using the predefined collectors to perform
65 * common mutable reduction tasks:
66 *
67 * <pre>{@code
68 * // Accumulate names into a List
69 * List<String> list = people.stream()
70 * .map(Person::getName)
71 * .collect(Collectors.toList());
72 *
73 * // Accumulate names into a TreeSet
74 * Set<String> set = people.stream()
75 * .map(Person::getName)
76 * .collect(Collectors.toCollection(TreeSet::new));
77 *
176 return (map, element) -> {
177 K k = keyMapper.apply(element);
178 V v = Objects.requireNonNull(valueMapper.apply(element));
179 V u = map.putIfAbsent(k, v);
180 if (u != null) throw duplicateKeyException(k, u, v);
181 };
182 }
183
184 @SuppressWarnings("unchecked")
185 private static <I, R> Function<I, R> castingIdentity() {
186 return i -> (R) i;
187 }
188
189 /**
190 * Simple implementation class for {@code Collector}.
191 *
192 * @param <T> the type of elements to be collected
193 * @param <R> the type of the result
194 */
195 static class CollectorImpl<T, A, R> implements Collector<T, A, R> {
196 private final Supplier<A> supplier;
197 private final BiConsumer<A, T> accumulator;
198 private final BinaryOperator<A> combiner;
199 private final Function<A, R> finisher;
200 private final Set<Characteristics> characteristics;
201
202 CollectorImpl(Supplier<A> supplier,
203 BiConsumer<A, T> accumulator,
204 BinaryOperator<A> combiner,
205 Function<A,R> finisher,
206 Set<Characteristics> characteristics) {
207 this.supplier = supplier;
208 this.accumulator = accumulator;
209 this.combiner = combiner;
210 this.finisher = finisher;
211 this.characteristics = characteristics;
212 }
213
214 CollectorImpl(Supplier<A> supplier,
215 BiConsumer<A, T> accumulator,
216 BinaryOperator<A> combiner,
217 Set<Characteristics> characteristics) {
218 this(supplier, accumulator, combiner, castingIdentity(), characteristics);
219 }
220
221 @Override
222 public BiConsumer<A, T> accumulator() {
223 return accumulator;
224 }
225
226 @Override
227 public Supplier<A> supplier() {
228 return supplier;
229 }
230
231 @Override
232 public BinaryOperator<A> combiner() {
233 return combiner;
234 }
235
236 @Override
237 public Function<A, R> finisher() {
238 return finisher;
239 }
240
241 @Override
242 public Set<Characteristics> characteristics() {
243 return characteristics;
244 }
245 }
246
247 /**
248 * Returns a {@code Collector} that accumulates the input elements into a
249 * new {@code Collection}, in encounter order. The {@code Collection} is
250 * created by the provided factory.
251 *
258 */
259 public static <T, C extends Collection<T>>
260 Collector<T, ?, C> toCollection(Supplier<C> collectionFactory) {
261 return new CollectorImpl<>(collectionFactory, Collection<T>::add,
262 (r1, r2) -> { r1.addAll(r2); return r1; },
263 CH_ID);
264 }
265
266 /**
267 * Returns a {@code Collector} that accumulates the input elements into a
268 * new {@code List}. There are no guarantees on the type, mutability,
269 * serializability, or thread-safety of the {@code List} returned; if more
270 * control over the returned {@code List} is required, use {@link #toCollection(Supplier)}.
271 *
272 * @param <T> the type of the input elements
273 * @return a {@code Collector} which collects all the input elements into a
274 * {@code List}, in encounter order
275 */
276 public static <T>
277 Collector<T, ?, List<T>> toList() {
278 return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
279 (left, right) -> { left.addAll(right); return left; },
280 CH_ID);
281 }
282
283 /**
284 * Returns a {@code Collector} that accumulates the input elements into an
285 * <a href="../List.html#unmodifiable">unmodifiable List</a> in encounter
286 * order. The returned Collector disallows null values and will throw
287 * {@code NullPointerException} if it is presented with a null value.
288 *
289 * @param <T> the type of the input elements
290 * @return a {@code Collector} that accumulates the input elements into an
291 * <a href="../List.html#unmodifiable">unmodifiable List</a> in encounter order
292 * @since 10
293 */
294 @SuppressWarnings("unchecked")
295 public static <T>
296 Collector<T, ?, List<T>> toUnmodifiableList() {
297 return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
298 (left, right) -> { left.addAll(right); return left; },
299 list -> (List<T>)List.of(list.toArray()),
300 CH_NOID);
301 }
302
303 /**
304 * Returns a {@code Collector} that accumulates the input elements into a
305 * new {@code Set}. There are no guarantees on the type, mutability,
306 * serializability, or thread-safety of the {@code Set} returned; if more
307 * control over the returned {@code Set} is required, use
308 * {@link #toCollection(Supplier)}.
309 *
310 * <p>This is an {@link Collector.Characteristics#UNORDERED unordered}
311 * Collector.
312 *
313 * @param <T> the type of the input elements
314 * @return a {@code Collector} which collects all the input elements into a
315 * {@code Set}
316 */
317 public static <T>
349 (left, right) -> {
350 if (left.size() < right.size()) {
351 right.addAll(left); return right;
352 } else {
353 left.addAll(right); return left;
354 }
355 },
356 set -> (Set<T>)Set.of(set.toArray()),
357 CH_UNORDERED_NOID);
358 }
359
360 /**
361 * Returns a {@code Collector} that concatenates the input elements into a
362 * {@code String}, in encounter order.
363 *
364 * @return a {@code Collector} that concatenates the input elements into a
365 * {@code String}, in encounter order
366 */
367 public static Collector<CharSequence, ?, String> joining() {
368 return new CollectorImpl<CharSequence, StringBuilder, String>(
369 StringBuilder::new, StringBuilder::append,
370 (r1, r2) -> { r1.append(r2); return r1; },
371 StringBuilder::toString, CH_NOID);
372 }
373
374 /**
375 * Returns a {@code Collector} that concatenates the input elements,
376 * separated by the specified delimiter, in encounter order.
377 *
378 * @param delimiter the delimiter to be used between each element
379 * @return A {@code Collector} which concatenates CharSequence elements,
380 * separated by the specified delimiter, in encounter order
381 */
382 public static Collector<CharSequence, ?, String> joining(CharSequence delimiter) {
383 return joining(delimiter, "", "");
384 }
385
386 /**
387 * Returns a {@code Collector} that concatenates the input elements,
388 * separated by the specified delimiter, with the specified prefix and
389 * suffix, in encounter order.
440 * Map<City, Set<String>> lastNamesByCity
441 * = people.stream().collect(
442 * groupingBy(Person::getCity,
443 * mapping(Person::getLastName,
444 * toSet())));
445 * }</pre>
446 *
447 * @param <T> the type of the input elements
448 * @param <U> type of elements accepted by downstream collector
449 * @param <A> intermediate accumulation type of the downstream collector
450 * @param <R> result type of collector
451 * @param mapper a function to be applied to the input elements
452 * @param downstream a collector which will accept mapped values
453 * @return a collector which applies the mapping function to the input
454 * elements and provides the mapped results to the downstream collector
455 */
456 public static <T, U, A, R>
457 Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper,
458 Collector<? super U, A, R> downstream) {
459 BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
460 return new CollectorImpl<>(downstream.supplier(),
461 (r, t) -> downstreamAccumulator.accept(r, mapper.apply(t)),
462 downstream.combiner(), downstream.finisher(),
463 downstream.characteristics());
464 }
465
466 /**
467 * Adapts a {@code Collector} accepting elements of type {@code U} to one
468 * accepting elements of type {@code T} by applying a flat mapping function
469 * to each input element before accumulation. The flat mapping function
470 * maps an input element to a {@link Stream stream} covering zero or more
471 * output elements that are then accumulated downstream. Each mapped stream
472 * is {@link java.util.stream.BaseStream#close() closed} after its contents
473 * have been placed downstream. (If a mapped stream is {@code null}
474 * an empty stream is used, instead.)
475 *
476 * @apiNote
477 * The {@code flatMapping()} collectors are most useful when used in a
478 * multi-level reduction, such as downstream of a {@code groupingBy} or
479 * {@code partitioningBy}. For example, given a stream of
480 * {@code Order}, to accumulate the set of line items for each customer:
485 * flatMapping(order -> order.getLineItems().stream(),
486 * toSet())));
487 * }</pre>
488 *
489 * @param <T> the type of the input elements
490 * @param <U> type of elements accepted by downstream collector
491 * @param <A> intermediate accumulation type of the downstream collector
492 * @param <R> result type of collector
493 * @param mapper a function to be applied to the input elements, which
494 * returns a stream of results
495 * @param downstream a collector which will receive the elements of the
496 * stream returned by mapper
497 * @return a collector which applies the mapping function to the input
498 * elements and provides the flat mapped results to the downstream collector
499 * @since 9
500 */
501 public static <T, U, A, R>
502 Collector<T, ?, R> flatMapping(Function<? super T, ? extends Stream<? extends U>> mapper,
503 Collector<? super U, A, R> downstream) {
504 BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
505 return new CollectorImpl<>(downstream.supplier(),
506 (r, t) -> {
507 try (Stream<? extends U> result = mapper.apply(t)) {
508 if (result != null)
509 result.sequential().forEach(u -> downstreamAccumulator.accept(r, u));
510 }
511 },
512 downstream.combiner(), downstream.finisher(),
513 downstream.characteristics());
514 }
515
516 /**
517 * Adapts a {@code Collector} to one accepting elements of the same type
518 * {@code T} by applying the predicate to each input element and only
519 * accumulating if the predicate returns {@code true}.
520 *
521 * @apiNote
522 * The {@code filtering()} collectors are most useful when used in a
523 * multi-level reduction, such as downstream of a {@code groupingBy} or
524 * {@code partitioningBy}. For example, given a stream of
525 * {@code Employee}, to accumulate the employees in each department that have a
535 * In this example, suppose there are no employees whose salary is above the
536 * threshold in some department. Using a filtering collector as shown above
537 * would result in a mapping from that department to an empty {@code Set}.
538 * If a stream {@code filter()} operation were done instead, there would be
539 * no mapping for that department at all.
540 *
541 * @param <T> the type of the input elements
542 * @param <A> intermediate accumulation type of the downstream collector
543 * @param <R> result type of collector
544 * @param predicate a predicate to be applied to the input elements
545 * @param downstream a collector which will accept values that match the
546 * predicate
547 * @return a collector which applies the predicate to the input elements
548 * and provides matching elements to the downstream collector
549 * @since 9
550 */
551 public static <T, A, R>
552 Collector<T, ?, R> filtering(Predicate<? super T> predicate,
553 Collector<? super T, A, R> downstream) {
554 BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
555 return new CollectorImpl<>(downstream.supplier(),
556 (r, t) -> {
557 if (predicate.test(t)) {
558 downstreamAccumulator.accept(r, t);
559 }
560 },
561 downstream.combiner(), downstream.finisher(),
562 downstream.characteristics());
563 }
564
565 /**
566 * Adapts a {@code Collector} to perform an additional finishing
567 * transformation. For example, one could adapt the {@link #toList()}
568 * collector to always produce an immutable list with:
569 * <pre>{@code
570 * List<String> list = people.stream().collect(
571 * collectingAndThen(toList(),
572 * Collections::unmodifiableList));
573 * }</pre>
574 *
575 * @param <T> the type of the input elements
576 * @param <A> intermediate accumulation type of the downstream collector
577 * @param <R> result type of the downstream collector
578 * @param <RR> result type of the resulting collector
579 * @param downstream a collector
580 * @param finisher a function to be applied to the final result of the downstream collector
581 * @return a collector which performs the action of the downstream collector,
582 * followed by an additional finishing step
583 */
584 public static<T,A,R,RR> Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream,
585 Function<R,RR> finisher) {
586 Set<Collector.Characteristics> characteristics = downstream.characteristics();
587 if (characteristics.contains(Collector.Characteristics.IDENTITY_FINISH)) {
588 if (characteristics.size() == 1)
589 characteristics = Collectors.CH_NOID;
590 else {
591 characteristics = EnumSet.copyOf(characteristics);
592 characteristics.remove(Collector.Characteristics.IDENTITY_FINISH);
593 characteristics = Collections.unmodifiableSet(characteristics);
594 }
595 }
596 return new CollectorImpl<>(downstream.supplier(),
597 downstream.accumulator(),
598 downstream.combiner(),
599 downstream.finisher().andThen(finisher),
600 characteristics);
601 }
602
603 /**
604 * Returns a {@code Collector} accepting elements of type {@code T} that
605 * counts the number of input elements. If no elements are present, the
606 * result is 0.
607 *
608 * @implSpec
609 * This produces a result equivalent to:
610 * <pre>{@code
611 * reducing(0L, e -> 1L, Long::sum)
612 * }</pre>
613 *
614 * @param <T> the type of the input elements
615 * @return a {@code Collector} that counts the input elements
616 */
1440 * order, using {@link #toConcurrentMap(Function, Function)}
1441 * may offer better parallel performance.
1442 *
1443 * @param <T> the type of the input elements
1444 * @param <K> the output type of the key mapping function
1445 * @param <U> the output type of the value mapping function
1446 * @param keyMapper a mapping function to produce keys
1447 * @param valueMapper a mapping function to produce values
1448 * @return a {@code Collector} which collects elements into a {@code Map}
1449 * whose keys and values are the result of applying mapping functions to
1450 * the input elements
1451 *
1452 * @see #toMap(Function, Function, BinaryOperator)
1453 * @see #toMap(Function, Function, BinaryOperator, Supplier)
1454 * @see #toConcurrentMap(Function, Function)
1455 */
1456 public static <T, K, U>
1457 Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
1458 Function<? super T, ? extends U> valueMapper) {
1459 return new CollectorImpl<>(HashMap::new,
1460 uniqKeysMapAccumulator(keyMapper, valueMapper),
1461 uniqKeysMapMerger(),
1462 CH_ID);
1463 }
1464
1465 /**
1466 * Returns a {@code Collector} that accumulates the input elements into an
1467 * <a href="../Map.html#unmodifiable">unmodifiable Map</a>,
1468 * whose keys and values are the result of applying the provided
1469 * mapping functions to the input elements.
1470 *
1471 * <p>If the mapped keys contain duplicates (according to
1472 * {@link Object#equals(Object)}), an {@code IllegalStateException} is
1473 * thrown when the collection operation is performed. If the mapped keys
1474 * might have duplicates, use {@link #toUnmodifiableMap(Function, Function, BinaryOperator)}
1475 * to handle merging of the values.
1476 *
1477 * <p>The returned Collector disallows null keys and values. If either mapping function
1478 * returns null, {@code NullPointerException} will be thrown.
1479 *
1699 * {@link Collector.Characteristics#UNORDERED unordered} Collector.
1700 *
1701 * @param <T> the type of the input elements
1702 * @param <K> the output type of the key mapping function
1703 * @param <U> the output type of the value mapping function
1704 * @param keyMapper the mapping function to produce keys
1705 * @param valueMapper the mapping function to produce values
1706 * @return a concurrent, unordered {@code Collector} which collects elements into a
1707 * {@code ConcurrentMap} whose keys are the result of applying a key mapping
1708 * function to the input elements, and whose values are the result of
1709 * applying a value mapping function to the input elements
1710 *
1711 * @see #toMap(Function, Function)
1712 * @see #toConcurrentMap(Function, Function, BinaryOperator)
1713 * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
1714 */
1715 public static <T, K, U>
1716 Collector<T, ?, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
1717 Function<? super T, ? extends U> valueMapper) {
1718 return new CollectorImpl<>(ConcurrentHashMap::new,
1719 uniqKeysMapAccumulator(keyMapper, valueMapper),
1720 uniqKeysMapMerger(),
1721 CH_CONCURRENT_ID);
1722 }
1723
1724 /**
1725 * Returns a concurrent {@code Collector} that accumulates elements into a
1726 * {@code ConcurrentMap} whose keys and values are the result of applying
1727 * the provided mapping functions to the input elements.
1728 *
1729 * <p>If the mapped keys contain duplicates (according to {@link Object#equals(Object)}),
1730 * the value mapping function is applied to each equal element, and the
1731 * results are merged using the provided merging function.
1732 *
1733 * <p>There are no guarantees on the type, mutability, or serializability
1734 * of the {@code ConcurrentMap} returned.
1735 *
1736 * @apiNote
1737 * There are multiple ways to deal with collisions between multiple elements
1738 * mapping to the same key. The other forms of {@code toConcurrentMap} simply use
1914 * @param downstream2 the second downstream collector
1915 * @param merger the function which merges two results into the single one
1916 * @return a {@code Collector} which aggregates the results of two supplied collectors.
1917 * @since 12
1918 */
1919 public static <T, R1, R2, R>
1920 Collector<T, ?, R> teeing(Collector<? super T, ?, R1> downstream1,
1921 Collector<? super T, ?, R2> downstream2,
1922 BiFunction<? super R1, ? super R2, R> merger) {
1923 return teeing0(downstream1, downstream2, merger);
1924 }
1925
1926 private static <T, A1, A2, R1, R2, R>
1927 Collector<T, ?, R> teeing0(Collector<? super T, A1, R1> downstream1,
1928 Collector<? super T, A2, R2> downstream2,
1929 BiFunction<? super R1, ? super R2, R> merger) {
1930 Objects.requireNonNull(downstream1, "downstream1");
1931 Objects.requireNonNull(downstream2, "downstream2");
1932 Objects.requireNonNull(merger, "merger");
1933
1934 Supplier<A1> c1Supplier = Objects.requireNonNull(downstream1.supplier(), "downstream1 supplier");
1935 Supplier<A2> c2Supplier = Objects.requireNonNull(downstream2.supplier(), "downstream2 supplier");
1936 BiConsumer<A1, ? super T> c1Accumulator =
1937 Objects.requireNonNull(downstream1.accumulator(), "downstream1 accumulator");
1938 BiConsumer<A2, ? super T> c2Accumulator =
1939 Objects.requireNonNull(downstream2.accumulator(), "downstream2 accumulator");
1940 BinaryOperator<A1> c1Combiner = Objects.requireNonNull(downstream1.combiner(), "downstream1 combiner");
1941 BinaryOperator<A2> c2Combiner = Objects.requireNonNull(downstream2.combiner(), "downstream2 combiner");
1942 Function<A1, R1> c1Finisher = Objects.requireNonNull(downstream1.finisher(), "downstream1 finisher");
1943 Function<A2, R2> c2Finisher = Objects.requireNonNull(downstream2.finisher(), "downstream2 finisher");
1944
1945 Set<Collector.Characteristics> characteristics;
1946 Set<Collector.Characteristics> c1Characteristics = downstream1.characteristics();
1947 Set<Collector.Characteristics> c2Characteristics = downstream2.characteristics();
1948 if (CH_ID.containsAll(c1Characteristics) || CH_ID.containsAll(c2Characteristics)) {
1949 characteristics = CH_NOID;
1950 } else {
1951 EnumSet<Collector.Characteristics> c = EnumSet.noneOf(Collector.Characteristics.class);
1952 c.addAll(c1Characteristics);
1953 c.retainAll(c2Characteristics);
1954 c.remove(Collector.Characteristics.IDENTITY_FINISH);
1955 characteristics = Collections.unmodifiableSet(c);
1956 }
1957
1958 class PairBox {
1959 A1 left = c1Supplier.get();
1960 A2 right = c2Supplier.get();
1961
1962 void add(T t) {
1963 c1Accumulator.accept(left, t);
1964 c2Accumulator.accept(right, t);
1965 }
1966
1967 PairBox combine(PairBox other) {
1968 left = c1Combiner.apply(left, other.left);
1969 right = c2Combiner.apply(right, other.right);
1970 return this;
1971 }
1972
1973 R get() {
1974 R1 r1 = c1Finisher.apply(left);
1975 R2 r2 = c2Finisher.apply(right);
1976 return merger.apply(r1, r2);
1977 }
1978 }
1979
1980 return new CollectorImpl<>(PairBox::new, PairBox::add, PairBox::combine, PairBox::get, characteristics);
1981 }
1982
1983 /**
1984 * Implementation class used by partitioningBy.
1985 */
1986 private static final class Partition<T>
1987 extends AbstractMap<Boolean, T>
1988 implements Map<Boolean, T> {
1989 final T forTrue;
1990 final T forFalse;
1991
1992 Partition(T forTrue, T forFalse) {
1993 this.forTrue = forTrue;
1994 this.forFalse = forFalse;
1995 }
1996
1997 @Override
1998 public Set<Map.Entry<Boolean, T>> entrySet() {
1999 return new AbstractSet<>() {
2000 @Override
|
28 import java.util.AbstractSet;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.Comparator;
33 import java.util.DoubleSummaryStatistics;
34 import java.util.EnumSet;
35 import java.util.HashMap;
36 import java.util.HashSet;
37 import java.util.IntSummaryStatistics;
38 import java.util.Iterator;
39 import java.util.List;
40 import java.util.LongSummaryStatistics;
41 import java.util.Map;
42 import java.util.Objects;
43 import java.util.Optional;
44 import java.util.Set;
45 import java.util.StringJoiner;
46 import java.util.concurrent.ConcurrentHashMap;
47 import java.util.concurrent.ConcurrentMap;
48 import java.util.function.*;
49
50 /**
51 * Implementations of {@link Collector} that implement various useful reduction
52 * operations, such as accumulating elements into collections, summarizing
53 * elements according to various criteria, etc.
54 *
55 * <p>The following are examples of using the predefined collectors to perform
56 * common mutable reduction tasks:
57 *
58 * <pre>{@code
59 * // Accumulate names into a List
60 * List<String> list = people.stream()
61 * .map(Person::getName)
62 * .collect(Collectors.toList());
63 *
64 * // Accumulate names into a TreeSet
65 * Set<String> set = people.stream()
66 * .map(Person::getName)
67 * .collect(Collectors.toCollection(TreeSet::new));
68 *
167 return (map, element) -> {
168 K k = keyMapper.apply(element);
169 V v = Objects.requireNonNull(valueMapper.apply(element));
170 V u = map.putIfAbsent(k, v);
171 if (u != null) throw duplicateKeyException(k, u, v);
172 };
173 }
174
175 @SuppressWarnings("unchecked")
176 private static <I, R> Function<I, R> castingIdentity() {
177 return i -> (R) i;
178 }
179
180 /**
181 * Simple implementation class for {@code Collector}.
182 *
183 * @param <T> the type of elements to be collected
184 * @param <R> the type of the result
185 */
186 static class CollectorImpl<T, A, R> implements Collector<T, A, R> {
187 private final IntFunction<A> sizedSupplier;
188 private final Supplier<A> supplier;
189 private final BiConsumer<A, T> accumulator;
190 private final BinaryOperator<A> combiner;
191 private final Function<A, R> finisher;
192 private final Set<Characteristics> characteristics;
193
194 CollectorImpl(IntFunction<A> sizedSupplier,
195 Supplier<A> supplier,
196 BiConsumer<A, T> accumulator,
197 BinaryOperator<A> combiner,
198 Function<A,R> finisher,
199 Set<Characteristics> characteristics) {
200 this.sizedSupplier = sizedSupplier;
201 this.supplier = supplier;
202 this.accumulator = accumulator;
203 this.combiner = combiner;
204 this.finisher = finisher;
205 this.characteristics = characteristics;
206 }
207
208 CollectorImpl(IntFunction<A> sizedSupplier,
209 Supplier<A> supplier,
210 BiConsumer<A, T> accumulator,
211 BinaryOperator<A> combiner,
212 Set<Characteristics> characteristics) {
213 this(sizedSupplier, supplier, accumulator, combiner, castingIdentity(), characteristics);
214 }
215
216 CollectorImpl(Supplier<A> supplier,
217 BiConsumer<A, T> accumulator,
218 BinaryOperator<A> combiner,
219 Function<A,R> finisher,
220 Set<Characteristics> characteristics) {
221 this(ignored -> supplier.get(), supplier, accumulator, combiner, finisher, characteristics);
222 }
223
224 CollectorImpl(Supplier<A> supplier,
225 BiConsumer<A, T> accumulator,
226 BinaryOperator<A> combiner,
227 Set<Characteristics> characteristics) {
228 this(supplier, accumulator, combiner, castingIdentity(), characteristics);
229 }
230
231 @Override
232 public BiConsumer<A, T> accumulator() {
233 return accumulator;
234 }
235
236 @Override
237 public Supplier<A> supplier() {
238 return supplier;
239 }
240
241 @Override
242 public IntFunction<A> sizedSupplier() {
243 return sizedSupplier;
244 }
245
246 @Override
247 public BinaryOperator<A> combiner() {
248 return combiner;
249 }
250
251 @Override
252 public Function<A, R> finisher() {
253 return finisher;
254 }
255
256 @Override
257 public Set<Characteristics> characteristics() {
258 return characteristics;
259 }
260 }
261
262 /**
263 * Returns a {@code Collector} that accumulates the input elements into a
264 * new {@code Collection}, in encounter order. The {@code Collection} is
265 * created by the provided factory.
266 *
273 */
274 public static <T, C extends Collection<T>>
275 Collector<T, ?, C> toCollection(Supplier<C> collectionFactory) {
276 return new CollectorImpl<>(collectionFactory, Collection<T>::add,
277 (r1, r2) -> { r1.addAll(r2); return r1; },
278 CH_ID);
279 }
280
281 /**
282 * Returns a {@code Collector} that accumulates the input elements into a
283 * new {@code List}. There are no guarantees on the type, mutability,
284 * serializability, or thread-safety of the {@code List} returned; if more
285 * control over the returned {@code List} is required, use {@link #toCollection(Supplier)}.
286 *
287 * @param <T> the type of the input elements
288 * @return a {@code Collector} which collects all the input elements into a
289 * {@code List}, in encounter order
290 */
291 public static <T>
292 Collector<T, ?, List<T>> toList() {
293 return new CollectorImpl<>((IntFunction<List<T>>) ArrayList::new,
294 (Supplier<List<T>>) ArrayList::new,
295 List::add,
296 (left, right) -> { left.addAll(right); return left; },
297 CH_ID);
298 }
299
300 /**
301 * Returns a {@code Collector} that accumulates the input elements into an
302 * <a href="../List.html#unmodifiable">unmodifiable List</a> in encounter
303 * order. The returned Collector disallows null values and will throw
304 * {@code NullPointerException} if it is presented with a null value.
305 *
306 * @param <T> the type of the input elements
307 * @return a {@code Collector} that accumulates the input elements into an
308 * <a href="../List.html#unmodifiable">unmodifiable List</a> in encounter order
309 * @since 10
310 */
311 @SuppressWarnings("unchecked")
312 public static <T>
313 Collector<T, ?, List<T>> toUnmodifiableList() {
314 return new CollectorImpl<>((IntFunction<List<T>>) ArrayList::new,
315 (Supplier<List<T>>) ArrayList::new,
316 List::add,
317 (left, right) -> { left.addAll(right); return left; },
318 list -> (List<T>)List.of(list.toArray()),
319 CH_NOID);
320 }
321
322 /**
323 * Returns a {@code Collector} that accumulates the input elements into a
324 * new {@code Set}. There are no guarantees on the type, mutability,
325 * serializability, or thread-safety of the {@code Set} returned; if more
326 * control over the returned {@code Set} is required, use
327 * {@link #toCollection(Supplier)}.
328 *
329 * <p>This is an {@link Collector.Characteristics#UNORDERED unordered}
330 * Collector.
331 *
332 * @param <T> the type of the input elements
333 * @return a {@code Collector} which collects all the input elements into a
334 * {@code Set}
335 */
336 public static <T>
368 (left, right) -> {
369 if (left.size() < right.size()) {
370 right.addAll(left); return right;
371 } else {
372 left.addAll(right); return left;
373 }
374 },
375 set -> (Set<T>)Set.of(set.toArray()),
376 CH_UNORDERED_NOID);
377 }
378
379 /**
380 * Returns a {@code Collector} that concatenates the input elements into a
381 * {@code String}, in encounter order.
382 *
383 * @return a {@code Collector} that concatenates the input elements into a
384 * {@code String}, in encounter order
385 */
386 public static Collector<CharSequence, ?, String> joining() {
387 return new CollectorImpl<CharSequence, StringBuilder, String>(
388 StringBuilder::new, StringBuilder::new, StringBuilder::append,
389 (r1, r2) -> { r1.append(r2); return r1; },
390 StringBuilder::toString, CH_NOID);
391 }
392
393 /**
394 * Returns a {@code Collector} that concatenates the input elements,
395 * separated by the specified delimiter, in encounter order.
396 *
397 * @param delimiter the delimiter to be used between each element
398 * @return A {@code Collector} which concatenates CharSequence elements,
399 * separated by the specified delimiter, in encounter order
400 */
401 public static Collector<CharSequence, ?, String> joining(CharSequence delimiter) {
402 return joining(delimiter, "", "");
403 }
404
405 /**
406 * Returns a {@code Collector} that concatenates the input elements,
407 * separated by the specified delimiter, with the specified prefix and
408 * suffix, in encounter order.
459 * Map<City, Set<String>> lastNamesByCity
460 * = people.stream().collect(
461 * groupingBy(Person::getCity,
462 * mapping(Person::getLastName,
463 * toSet())));
464 * }</pre>
465 *
466 * @param <T> the type of the input elements
467 * @param <U> type of elements accepted by downstream collector
468 * @param <A> intermediate accumulation type of the downstream collector
469 * @param <R> result type of collector
470 * @param mapper a function to be applied to the input elements
471 * @param downstream a collector which will accept mapped values
472 * @return a collector which applies the mapping function to the input
473 * elements and provides the mapped results to the downstream collector
474 */
475 public static <T, U, A, R>
476 Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper,
477 Collector<? super U, A, R> downstream) {
478 BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
479 return new CollectorImpl<>(downstream.sizedSupplier(), downstream.supplier(),
480 (r, t) -> downstreamAccumulator.accept(r, mapper.apply(t)),
481 downstream.combiner(), downstream.finisher(),
482 downstream.characteristics());
483 }
484
485 /**
486 * Adapts a {@code Collector} accepting elements of type {@code U} to one
487 * accepting elements of type {@code T} by applying a flat mapping function
488 * to each input element before accumulation. The flat mapping function
489 * maps an input element to a {@link Stream stream} covering zero or more
490 * output elements that are then accumulated downstream. Each mapped stream
491 * is {@link java.util.stream.BaseStream#close() closed} after its contents
492 * have been placed downstream. (If a mapped stream is {@code null}
493 * an empty stream is used, instead.)
494 *
495 * @apiNote
496 * The {@code flatMapping()} collectors are most useful when used in a
497 * multi-level reduction, such as downstream of a {@code groupingBy} or
498 * {@code partitioningBy}. For example, given a stream of
499 * {@code Order}, to accumulate the set of line items for each customer:
504 * flatMapping(order -> order.getLineItems().stream(),
505 * toSet())));
506 * }</pre>
507 *
508 * @param <T> the type of the input elements
509 * @param <U> type of elements accepted by downstream collector
510 * @param <A> intermediate accumulation type of the downstream collector
511 * @param <R> result type of collector
512 * @param mapper a function to be applied to the input elements, which
513 * returns a stream of results
514 * @param downstream a collector which will receive the elements of the
515 * stream returned by mapper
516 * @return a collector which applies the mapping function to the input
517 * elements and provides the flat mapped results to the downstream collector
518 * @since 9
519 */
520 public static <T, U, A, R>
521 Collector<T, ?, R> flatMapping(Function<? super T, ? extends Stream<? extends U>> mapper,
522 Collector<? super U, A, R> downstream) {
523 BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
524 return new CollectorImpl<>(downstream.sizedSupplier(), downstream.supplier(),
525 (r, t) -> {
526 try (Stream<? extends U> result = mapper.apply(t)) {
527 if (result != null)
528 result.sequential().forEach(u -> downstreamAccumulator.accept(r, u));
529 }
530 },
531 downstream.combiner(), downstream.finisher(),
532 downstream.characteristics());
533 }
534
535 /**
536 * Adapts a {@code Collector} to one accepting elements of the same type
537 * {@code T} by applying the predicate to each input element and only
538 * accumulating if the predicate returns {@code true}.
539 *
540 * @apiNote
541 * The {@code filtering()} collectors are most useful when used in a
542 * multi-level reduction, such as downstream of a {@code groupingBy} or
543 * {@code partitioningBy}. For example, given a stream of
544 * {@code Employee}, to accumulate the employees in each department that have a
554 * In this example, suppose there are no employees whose salary is above the
555 * threshold in some department. Using a filtering collector as shown above
556 * would result in a mapping from that department to an empty {@code Set}.
557 * If a stream {@code filter()} operation were done instead, there would be
558 * no mapping for that department at all.
559 *
560 * @param <T> the type of the input elements
561 * @param <A> intermediate accumulation type of the downstream collector
562 * @param <R> result type of collector
563 * @param predicate a predicate to be applied to the input elements
564 * @param downstream a collector which will accept values that match the
565 * predicate
566 * @return a collector which applies the predicate to the input elements
567 * and provides matching elements to the downstream collector
568 * @since 9
569 */
570 public static <T, A, R>
571 Collector<T, ?, R> filtering(Predicate<? super T> predicate,
572 Collector<? super T, A, R> downstream) {
573 BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
574 return new CollectorImpl<>(downstream.sizedSupplier(), downstream.supplier(),
575 (r, t) -> {
576 if (predicate.test(t)) {
577 downstreamAccumulator.accept(r, t);
578 }
579 },
580 downstream.combiner(), downstream.finisher(),
581 downstream.characteristics());
582 }
583
584 /**
585 * Adapts a {@code Collector} to perform an additional finishing
586 * transformation. For example, one could adapt the {@link #toList()}
587 * collector to always produce an immutable list with:
588 * <pre>{@code
589 * List<String> list = people.stream().collect(
590 * collectingAndThen(toList(),
591 * Collections::unmodifiableList));
592 * }</pre>
593 *
594 * @param <T> the type of the input elements
595 * @param <A> intermediate accumulation type of the downstream collector
596 * @param <R> result type of the downstream collector
597 * @param <RR> result type of the resulting collector
598 * @param downstream a collector
599 * @param finisher a function to be applied to the final result of the downstream collector
600 * @return a collector which performs the action of the downstream collector,
601 * followed by an additional finishing step
602 */
603 public static<T,A,R,RR> Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream,
604 Function<R,RR> finisher) {
605 Set<Collector.Characteristics> characteristics = downstream.characteristics();
606 if (characteristics.contains(Collector.Characteristics.IDENTITY_FINISH)) {
607 if (characteristics.size() == 1)
608 characteristics = Collectors.CH_NOID;
609 else {
610 characteristics = EnumSet.copyOf(characteristics);
611 characteristics.remove(Collector.Characteristics.IDENTITY_FINISH);
612 characteristics = Collections.unmodifiableSet(characteristics);
613 }
614 }
615 return new CollectorImpl<>(downstream.sizedSupplier(),
616 downstream.supplier(),
617 downstream.accumulator(),
618 downstream.combiner(),
619 downstream.finisher().andThen(finisher),
620 characteristics);
621 }
622
623 /**
624 * Returns a {@code Collector} accepting elements of type {@code T} that
625 * counts the number of input elements. If no elements are present, the
626 * result is 0.
627 *
628 * @implSpec
629 * This produces a result equivalent to:
630 * <pre>{@code
631 * reducing(0L, e -> 1L, Long::sum)
632 * }</pre>
633 *
634 * @param <T> the type of the input elements
635 * @return a {@code Collector} that counts the input elements
636 */
1460 * order, using {@link #toConcurrentMap(Function, Function)}
1461 * may offer better parallel performance.
1462 *
1463 * @param <T> the type of the input elements
1464 * @param <K> the output type of the key mapping function
1465 * @param <U> the output type of the value mapping function
1466 * @param keyMapper a mapping function to produce keys
1467 * @param valueMapper a mapping function to produce values
1468 * @return a {@code Collector} which collects elements into a {@code Map}
1469 * whose keys and values are the result of applying mapping functions to
1470 * the input elements
1471 *
1472 * @see #toMap(Function, Function, BinaryOperator)
1473 * @see #toMap(Function, Function, BinaryOperator, Supplier)
1474 * @see #toConcurrentMap(Function, Function)
1475 */
1476 public static <T, K, U>
1477 Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
1478 Function<? super T, ? extends U> valueMapper) {
1479 return new CollectorImpl<>(HashMap::new,
1480 HashMap::new,
1481 uniqKeysMapAccumulator(keyMapper, valueMapper),
1482 uniqKeysMapMerger(),
1483 CH_ID);
1484 }
1485
1486 /**
1487 * Returns a {@code Collector} that accumulates the input elements into an
1488 * <a href="../Map.html#unmodifiable">unmodifiable Map</a>,
1489 * whose keys and values are the result of applying the provided
1490 * mapping functions to the input elements.
1491 *
1492 * <p>If the mapped keys contain duplicates (according to
1493 * {@link Object#equals(Object)}), an {@code IllegalStateException} is
1494 * thrown when the collection operation is performed. If the mapped keys
1495 * might have duplicates, use {@link #toUnmodifiableMap(Function, Function, BinaryOperator)}
1496 * to handle merging of the values.
1497 *
1498 * <p>The returned Collector disallows null keys and values. If either mapping function
1499 * returns null, {@code NullPointerException} will be thrown.
1500 *
1720 * {@link Collector.Characteristics#UNORDERED unordered} Collector.
1721 *
1722 * @param <T> the type of the input elements
1723 * @param <K> the output type of the key mapping function
1724 * @param <U> the output type of the value mapping function
1725 * @param keyMapper the mapping function to produce keys
1726 * @param valueMapper the mapping function to produce values
1727 * @return a concurrent, unordered {@code Collector} which collects elements into a
1728 * {@code ConcurrentMap} whose keys are the result of applying a key mapping
1729 * function to the input elements, and whose values are the result of
1730 * applying a value mapping function to the input elements
1731 *
1732 * @see #toMap(Function, Function)
1733 * @see #toConcurrentMap(Function, Function, BinaryOperator)
1734 * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
1735 */
1736 public static <T, K, U>
1737 Collector<T, ?, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
1738 Function<? super T, ? extends U> valueMapper) {
1739 return new CollectorImpl<>(ConcurrentHashMap::new,
1740 ConcurrentHashMap::new,
1741 uniqKeysMapAccumulator(keyMapper, valueMapper),
1742 uniqKeysMapMerger(),
1743 CH_CONCURRENT_ID);
1744 }
1745
1746 /**
1747 * Returns a concurrent {@code Collector} that accumulates elements into a
1748 * {@code ConcurrentMap} whose keys and values are the result of applying
1749 * the provided mapping functions to the input elements.
1750 *
1751 * <p>If the mapped keys contain duplicates (according to {@link Object#equals(Object)}),
1752 * the value mapping function is applied to each equal element, and the
1753 * results are merged using the provided merging function.
1754 *
1755 * <p>There are no guarantees on the type, mutability, or serializability
1756 * of the {@code ConcurrentMap} returned.
1757 *
1758 * @apiNote
1759 * There are multiple ways to deal with collisions between multiple elements
1760 * mapping to the same key. The other forms of {@code toConcurrentMap} simply use
1936 * @param downstream2 the second downstream collector
1937 * @param merger the function which merges two results into the single one
1938 * @return a {@code Collector} which aggregates the results of two supplied collectors.
1939 * @since 12
1940 */
1941 public static <T, R1, R2, R>
1942 Collector<T, ?, R> teeing(Collector<? super T, ?, R1> downstream1,
1943 Collector<? super T, ?, R2> downstream2,
1944 BiFunction<? super R1, ? super R2, R> merger) {
1945 return teeing0(downstream1, downstream2, merger);
1946 }
1947
1948 private static <T, A1, A2, R1, R2, R>
1949 Collector<T, ?, R> teeing0(Collector<? super T, A1, R1> downstream1,
1950 Collector<? super T, A2, R2> downstream2,
1951 BiFunction<? super R1, ? super R2, R> merger) {
1952 Objects.requireNonNull(downstream1, "downstream1");
1953 Objects.requireNonNull(downstream2, "downstream2");
1954 Objects.requireNonNull(merger, "merger");
1955
1956 BiConsumer<A1, ? super T> c1Accumulator =
1957 Objects.requireNonNull(downstream1.accumulator(), "downstream1 accumulator");
1958 BiConsumer<A2, ? super T> c2Accumulator =
1959 Objects.requireNonNull(downstream2.accumulator(), "downstream2 accumulator");
1960 BinaryOperator<A1> c1Combiner = Objects.requireNonNull(downstream1.combiner(), "downstream1 combiner");
1961 BinaryOperator<A2> c2Combiner = Objects.requireNonNull(downstream2.combiner(), "downstream2 combiner");
1962 Function<A1, R1> c1Finisher = Objects.requireNonNull(downstream1.finisher(), "downstream1 finisher");
1963 Function<A2, R2> c2Finisher = Objects.requireNonNull(downstream2.finisher(), "downstream2 finisher");
1964
1965 Set<Collector.Characteristics> characteristics;
1966 Set<Collector.Characteristics> c1Characteristics = downstream1.characteristics();
1967 Set<Collector.Characteristics> c2Characteristics = downstream2.characteristics();
1968 if (CH_ID.containsAll(c1Characteristics) || CH_ID.containsAll(c2Characteristics)) {
1969 characteristics = CH_NOID;
1970 } else {
1971 EnumSet<Collector.Characteristics> c = EnumSet.noneOf(Collector.Characteristics.class);
1972 c.addAll(c1Characteristics);
1973 c.retainAll(c2Characteristics);
1974 c.remove(Collector.Characteristics.IDENTITY_FINISH);
1975 characteristics = Collections.unmodifiableSet(c);
1976 }
1977
1978 class PairBox {
1979 A1 left;
1980 A2 right;
1981
1982 PairBox(int initialSize) {
1983 left = Objects.requireNonNull(downstream1.sizedSupplier(), "downstream1 sizedSupplier")
1984 .apply(initialSize);
1985 right = Objects.requireNonNull(downstream2.sizedSupplier(), "downstream2 sizedSupplier")
1986 .apply(initialSize);
1987 }
1988
1989 PairBox() {
1990 left = Objects.requireNonNull(downstream1.supplier(), "downstream1 supplier").get();
1991 right = Objects.requireNonNull(downstream2.supplier(), "downstream2 supplier").get();
1992 }
1993
1994 void add(T t) {
1995 c1Accumulator.accept(left, t);
1996 c2Accumulator.accept(right, t);
1997 }
1998
1999 PairBox combine(PairBox other) {
2000 left = c1Combiner.apply(left, other.left);
2001 right = c2Combiner.apply(right, other.right);
2002 return this;
2003 }
2004
2005 R get() {
2006 R1 r1 = c1Finisher.apply(left);
2007 R2 r2 = c2Finisher.apply(right);
2008 return merger.apply(r1, r2);
2009 }
2010 }
2011
2012 return new CollectorImpl<>(PairBox::new,
2013 PairBox::new,
2014 PairBox::add,
2015 PairBox::combine,
2016 PairBox::get,
2017 characteristics);
2018 }
2019
2020 /**
2021 * Implementation class used by partitioningBy.
2022 */
2023 private static final class Partition<T>
2024 extends AbstractMap<Boolean, T>
2025 implements Map<Boolean, T> {
2026 final T forTrue;
2027 final T forFalse;
2028
2029 Partition(T forTrue, T forFalse) {
2030 this.forTrue = forTrue;
2031 this.forFalse = forFalse;
2032 }
2033
2034 @Override
2035 public Set<Map.Entry<Boolean, T>> entrySet() {
2036 return new AbstractSet<>() {
2037 @Override
|