< prev index next >

src/java.base/share/classes/java/util/stream/Collectors.java

Print this page




  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
< prev index next >