1 /*
   2  * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package java.util.stream;
  26 
  27 import java.util.AbstractMap;
  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  *
  69  * // Convert elements to strings and concatenate them, separated by commas
  70  * String joined = things.stream()
  71  *   .map(Object::toString)
  72  *   .collect(Collectors.joining(", "));
  73  *
  74  * // Compute sum of salaries of employee
  75  * int total = employees.stream()
  76  *   .collect(Collectors.summingInt(Employee::getSalary));
  77  *
  78  * // Group employees by department
  79  * Map<Department, List<Employee>> byDept = employees.stream()
  80  *   .collect(Collectors.groupingBy(Employee::getDepartment));
  81  *
  82  * // Compute sum of salaries by department
  83  * Map<Department, Integer> totalByDept = employees.stream()
  84  *   .collect(Collectors.groupingBy(Employee::getDepartment,
  85  *                                  Collectors.summingInt(Employee::getSalary)));
  86  *
  87  * // Partition students into passing and failing
  88  * Map<Boolean, List<Student>> passingFailing = students.stream()
  89  *   .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
  90  *
  91  * }</pre>
  92  *
  93  * @since 1.8
  94  */
  95 public final class Collectors {
  96 
  97     static final Set<Collector.Characteristics> CH_CONCURRENT_ID
  98             = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.CONCURRENT,
  99                                                      Collector.Characteristics.UNORDERED,
 100                                                      Collector.Characteristics.IDENTITY_FINISH));
 101     static final Set<Collector.Characteristics> CH_CONCURRENT_NOID
 102             = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.CONCURRENT,
 103                                                      Collector.Characteristics.UNORDERED));
 104     static final Set<Collector.Characteristics> CH_ID
 105             = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH));
 106     static final Set<Collector.Characteristics> CH_UNORDERED_ID
 107             = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.UNORDERED,
 108                                                      Collector.Characteristics.IDENTITY_FINISH));
 109     static final Set<Collector.Characteristics> CH_NOID = Collections.emptySet();
 110     static final Set<Collector.Characteristics> CH_UNORDERED_NOID
 111             = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.UNORDERED));
 112 
 113     private Collectors() { }
 114 
 115     /**
 116      * Construct an {@code IllegalStateException} with appropriate message.
 117      *
 118      * @param k the duplicate key
 119      * @param u 1st value to be accumulated/merged
 120      * @param v 2nd value to be accumulated/merged
 121      */
 122     private static IllegalStateException duplicateKeyException(
 123             Object k, Object u, Object v) {
 124         return new IllegalStateException(String.format(
 125             "Duplicate key %s (attempted merging values %s and %s)",
 126             k, u, v));
 127     }
 128 
 129     /**
 130      * {@code BinaryOperator<Map>} that merges the contents of its right
 131      * argument into its left argument, throwing {@code IllegalStateException}
 132      * if duplicate keys are encountered.
 133      *
 134      * @param <K> type of the map keys
 135      * @param <V> type of the map values
 136      * @param <M> type of the map
 137      * @return a merge function for two maps
 138      */
 139     private static <K, V, M extends Map<K,V>>
 140     BinaryOperator<M> uniqKeysMapMerger() {
 141         return (m1, m2) -> {
 142             for (Map.Entry<K,V> e : m2.entrySet()) {
 143                 K k = e.getKey();
 144                 V v = Objects.requireNonNull(e.getValue());
 145                 V u = m1.putIfAbsent(k, v);
 146                 if (u != null) throw duplicateKeyException(k, u, v);
 147             }
 148             return m1;
 149         };
 150     }
 151 
 152     /**
 153      * {@code BiConsumer<Map, T>} that accumulates (key, value) pairs
 154      * extracted from elements into the map, throwing {@code IllegalStateException}
 155      * if duplicate keys are encountered.
 156      *
 157      * @param keyMapper a function that maps an element into a key
 158      * @param valueMapper a function that maps an element into a value
 159      * @param <T> type of elements
 160      * @param <K> type of map keys
 161      * @param <V> type of map values
 162      * @return an accumulating consumer
 163      */
 164     private static <T, K, V>
 165     BiConsumer<Map<K, V>, T> uniqKeysMapAccumulator(Function<? super T, ? extends K> keyMapper,
 166                                                     Function<? super T, ? extends V> valueMapper) {
 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      *
 267      * @param <T> the type of the input elements
 268      * @param <C> the type of the resulting {@code Collection}
 269      * @param collectionFactory a supplier providing a new empty {@code Collection}
 270      *                          into which the results will be inserted
 271      * @return a {@code Collector} which collects all the input elements into a
 272      * {@code Collection}, in encounter order
 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>
 337     Collector<T, ?, Set<T>> toSet() {
 338         return new CollectorImpl<>((Supplier<Set<T>>) HashSet::new, Set::add,
 339                                    (left, right) -> {
 340                                        if (left.size() < right.size()) {
 341                                            right.addAll(left); return right;
 342                                        } else {
 343                                            left.addAll(right); return left;
 344                                        }
 345                                    },
 346                                    CH_UNORDERED_ID);
 347     }
 348 
 349     /**
 350      * Returns a {@code Collector} that accumulates the input elements into an
 351      * <a href="../Set.html#unmodifiable">unmodifiable Set</a>. The returned
 352      * Collector disallows null values and will throw {@code NullPointerException}
 353      * if it is presented with a null value. If the input contains duplicate elements,
 354      * an arbitrary element of the duplicates is preserved.
 355      *
 356      * <p>This is an {@link Collector.Characteristics#UNORDERED unordered}
 357      * Collector.
 358      *
 359      * @param <T> the type of the input elements
 360      * @return a {@code Collector} that accumulates the input elements into an
 361      * <a href="../Set.html#unmodifiable">unmodifiable Set</a>
 362      * @since 10
 363      */
 364     @SuppressWarnings("unchecked")
 365     public static <T>
 366     Collector<T, ?, Set<T>> toUnmodifiableSet() {
 367         return new CollectorImpl<>((Supplier<Set<T>>) HashSet::new, Set::add,
 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::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.
 409      *
 410      * @param delimiter the delimiter to be used between each element
 411      * @param  prefix the sequence of characters to be used at the beginning
 412      *                of the joined result
 413      * @param  suffix the sequence of characters to be used at the end
 414      *                of the joined result
 415      * @return A {@code Collector} which concatenates CharSequence elements,
 416      * separated by the specified delimiter, in encounter order
 417      */
 418     public static Collector<CharSequence, ?, String> joining(CharSequence delimiter,
 419                                                              CharSequence prefix,
 420                                                              CharSequence suffix) {
 421         return new CollectorImpl<>(
 422                 () -> new StringJoiner(delimiter, prefix, suffix),
 423                 StringJoiner::add, StringJoiner::merge,
 424                 StringJoiner::toString, CH_NOID);
 425     }
 426 
 427     /**
 428      * {@code BinaryOperator<Map>} that merges the contents of its right
 429      * argument into its left argument, using the provided merge function to
 430      * handle duplicate keys.
 431      *
 432      * @param <K> type of the map keys
 433      * @param <V> type of the map values
 434      * @param <M> type of the map
 435      * @param mergeFunction A merge function suitable for
 436      * {@link Map#merge(Object, Object, BiFunction) Map.merge()}
 437      * @return a merge function for two maps
 438      */
 439     private static <K, V, M extends Map<K,V>>
 440     BinaryOperator<M> mapMerger(BinaryOperator<V> mergeFunction) {
 441         return (m1, m2) -> {
 442             for (Map.Entry<K,V> e : m2.entrySet())
 443                 m1.merge(e.getKey(), e.getValue(), mergeFunction);
 444             return m1;
 445         };
 446     }
 447 
 448     /**
 449      * Adapts a {@code Collector} accepting elements of type {@code U} to one
 450      * accepting elements of type {@code T} by applying a mapping function to
 451      * each input element before accumulation.
 452      *
 453      * @apiNote
 454      * The {@code mapping()} collectors are most useful when used in a
 455      * multi-level reduction, such as downstream of a {@code groupingBy} or
 456      * {@code partitioningBy}.  For example, given a stream of
 457      * {@code Person}, to accumulate the set of last names in each city:
 458      * <pre>{@code
 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:
 500      * <pre>{@code
 501      * Map<String, Set<LineItem>> itemsByCustomerName
 502      *   = orders.stream().collect(
 503      *     groupingBy(Order::getCustomerName,
 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.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
 545      * salary above a certain threshold:
 546      * <pre>{@code
 547      * Map<Department, Set<Employee>> wellPaidEmployeesByDepartment
 548      *   = employees.stream().collect(
 549      *     groupingBy(Employee::getDepartment,
 550      *                filtering(e -> e.getSalary() > 2000,
 551      *                          toSet())));
 552      * }</pre>
 553      * A filtering collector differs from a stream's {@code filter()} operation.
 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.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      */
 637     public static <T> Collector<T, ?, Long>
 638     counting() {
 639         return summingLong(e -> 1L);
 640     }
 641 
 642     /**
 643      * Returns a {@code Collector} that produces the minimal element according
 644      * to a given {@code Comparator}, described as an {@code Optional<T>}.
 645      *
 646      * @implSpec
 647      * This produces a result equivalent to:
 648      * <pre>{@code
 649      *     reducing(BinaryOperator.minBy(comparator))
 650      * }</pre>
 651      *
 652      * @param <T> the type of the input elements
 653      * @param comparator a {@code Comparator} for comparing elements
 654      * @return a {@code Collector} that produces the minimal value
 655      */
 656     public static <T> Collector<T, ?, Optional<T>>
 657     minBy(Comparator<? super T> comparator) {
 658         return reducing(BinaryOperator.minBy(comparator));
 659     }
 660 
 661     /**
 662      * Returns a {@code Collector} that produces the maximal element according
 663      * to a given {@code Comparator}, described as an {@code Optional<T>}.
 664      *
 665      * @implSpec
 666      * This produces a result equivalent to:
 667      * <pre>{@code
 668      *     reducing(BinaryOperator.maxBy(comparator))
 669      * }</pre>
 670      *
 671      * @param <T> the type of the input elements
 672      * @param comparator a {@code Comparator} for comparing elements
 673      * @return a {@code Collector} that produces the maximal value
 674      */
 675     public static <T> Collector<T, ?, Optional<T>>
 676     maxBy(Comparator<? super T> comparator) {
 677         return reducing(BinaryOperator.maxBy(comparator));
 678     }
 679 
 680     /**
 681      * Returns a {@code Collector} that produces the sum of a integer-valued
 682      * function applied to the input elements.  If no elements are present,
 683      * the result is 0.
 684      *
 685      * @param <T> the type of the input elements
 686      * @param mapper a function extracting the property to be summed
 687      * @return a {@code Collector} that produces the sum of a derived property
 688      */
 689     public static <T> Collector<T, ?, Integer>
 690     summingInt(ToIntFunction<? super T> mapper) {
 691         return new CollectorImpl<>(
 692                 () -> new int[1],
 693                 (a, t) -> { a[0] += mapper.applyAsInt(t); },
 694                 (a, b) -> { a[0] += b[0]; return a; },
 695                 a -> a[0], CH_NOID);
 696     }
 697 
 698     /**
 699      * Returns a {@code Collector} that produces the sum of a long-valued
 700      * function applied to the input elements.  If no elements are present,
 701      * the result is 0.
 702      *
 703      * @param <T> the type of the input elements
 704      * @param mapper a function extracting the property to be summed
 705      * @return a {@code Collector} that produces the sum of a derived property
 706      */
 707     public static <T> Collector<T, ?, Long>
 708     summingLong(ToLongFunction<? super T> mapper) {
 709         return new CollectorImpl<>(
 710                 () -> new long[1],
 711                 (a, t) -> { a[0] += mapper.applyAsLong(t); },
 712                 (a, b) -> { a[0] += b[0]; return a; },
 713                 a -> a[0], CH_NOID);
 714     }
 715 
 716     /**
 717      * Returns a {@code Collector} that produces the sum of a double-valued
 718      * function applied to the input elements.  If no elements are present,
 719      * the result is 0.
 720      *
 721      * <p>The sum returned can vary depending upon the order in which
 722      * values are recorded, due to accumulated rounding error in
 723      * addition of values of differing magnitudes. Values sorted by increasing
 724      * absolute magnitude tend to yield more accurate results.  If any recorded
 725      * value is a {@code NaN} or the sum is at any point a {@code NaN} then the
 726      * sum will be {@code NaN}.
 727      *
 728      * @param <T> the type of the input elements
 729      * @param mapper a function extracting the property to be summed
 730      * @return a {@code Collector} that produces the sum of a derived property
 731      */
 732     public static <T> Collector<T, ?, Double>
 733     summingDouble(ToDoubleFunction<? super T> mapper) {
 734         /*
 735          * In the arrays allocated for the collect operation, index 0
 736          * holds the high-order bits of the running sum, index 1 holds
 737          * the low-order bits of the sum computed via compensated
 738          * summation, and index 2 holds the simple sum used to compute
 739          * the proper result if the stream contains infinite values of
 740          * the same sign.
 741          */
 742         return new CollectorImpl<>(
 743                 () -> new double[3],
 744                 (a, t) -> { double val = mapper.applyAsDouble(t);
 745                             sumWithCompensation(a, val);
 746                             a[2] += val;},
 747                 (a, b) -> { sumWithCompensation(a, b[0]);
 748                             a[2] += b[2];
 749                             return sumWithCompensation(a, b[1]); },
 750                 a -> computeFinalSum(a),
 751                 CH_NOID);
 752     }
 753 
 754     /**
 755      * Incorporate a new double value using Kahan summation /
 756      * compensation summation.
 757      *
 758      * High-order bits of the sum are in intermediateSum[0], low-order
 759      * bits of the sum are in intermediateSum[1], any additional
 760      * elements are application-specific.
 761      *
 762      * @param intermediateSum the high-order and low-order words of the intermediate sum
 763      * @param value the name value to be included in the running sum
 764      */
 765     static double[] sumWithCompensation(double[] intermediateSum, double value) {
 766         double tmp = value - intermediateSum[1];
 767         double sum = intermediateSum[0];
 768         double velvel = sum + tmp; // Little wolf of rounding error
 769         intermediateSum[1] = (velvel - sum) - tmp;
 770         intermediateSum[0] = velvel;
 771         return intermediateSum;
 772     }
 773 
 774     /**
 775      * If the compensated sum is spuriously NaN from accumulating one
 776      * or more same-signed infinite values, return the
 777      * correctly-signed infinity stored in the simple sum.
 778      */
 779     static double computeFinalSum(double[] summands) {
 780         // Better error bounds to add both terms as the final sum
 781         double tmp = summands[0] + summands[1];
 782         double simpleSum = summands[summands.length - 1];
 783         if (Double.isNaN(tmp) && Double.isInfinite(simpleSum))
 784             return simpleSum;
 785         else
 786             return tmp;
 787     }
 788 
 789     /**
 790      * Returns a {@code Collector} that produces the arithmetic mean of an integer-valued
 791      * function applied to the input elements.  If no elements are present,
 792      * the result is 0.
 793      *
 794      * @param <T> the type of the input elements
 795      * @param mapper a function extracting the property to be averaged
 796      * @return a {@code Collector} that produces the arithmetic mean of a
 797      * derived property
 798      */
 799     public static <T> Collector<T, ?, Double>
 800     averagingInt(ToIntFunction<? super T> mapper) {
 801         return new CollectorImpl<>(
 802                 () -> new long[2],
 803                 (a, t) -> { a[0] += mapper.applyAsInt(t); a[1]++; },
 804                 (a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; },
 805                 a -> (a[1] == 0) ? 0.0d : (double) a[0] / a[1], CH_NOID);
 806     }
 807 
 808     /**
 809      * Returns a {@code Collector} that produces the arithmetic mean of a long-valued
 810      * function applied to the input elements.  If no elements are present,
 811      * the result is 0.
 812      *
 813      * @param <T> the type of the input elements
 814      * @param mapper a function extracting the property to be averaged
 815      * @return a {@code Collector} that produces the arithmetic mean of a
 816      * derived property
 817      */
 818     public static <T> Collector<T, ?, Double>
 819     averagingLong(ToLongFunction<? super T> mapper) {
 820         return new CollectorImpl<>(
 821                 () -> new long[2],
 822                 (a, t) -> { a[0] += mapper.applyAsLong(t); a[1]++; },
 823                 (a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; },
 824                 a -> (a[1] == 0) ? 0.0d : (double) a[0] / a[1], CH_NOID);
 825     }
 826 
 827     /**
 828      * Returns a {@code Collector} that produces the arithmetic mean of a double-valued
 829      * function applied to the input elements.  If no elements are present,
 830      * the result is 0.
 831      *
 832      * <p>The average returned can vary depending upon the order in which
 833      * values are recorded, due to accumulated rounding error in
 834      * addition of values of differing magnitudes. Values sorted by increasing
 835      * absolute magnitude tend to yield more accurate results.  If any recorded
 836      * value is a {@code NaN} or the sum is at any point a {@code NaN} then the
 837      * average will be {@code NaN}.
 838      *
 839      * @implNote The {@code double} format can represent all
 840      * consecutive integers in the range -2<sup>53</sup> to
 841      * 2<sup>53</sup>. If the pipeline has more than 2<sup>53</sup>
 842      * values, the divisor in the average computation will saturate at
 843      * 2<sup>53</sup>, leading to additional numerical errors.
 844      *
 845      * @param <T> the type of the input elements
 846      * @param mapper a function extracting the property to be averaged
 847      * @return a {@code Collector} that produces the arithmetic mean of a
 848      * derived property
 849      */
 850     public static <T> Collector<T, ?, Double>
 851     averagingDouble(ToDoubleFunction<? super T> mapper) {
 852         /*
 853          * In the arrays allocated for the collect operation, index 0
 854          * holds the high-order bits of the running sum, index 1 holds
 855          * the low-order bits of the sum computed via compensated
 856          * summation, and index 2 holds the number of values seen.
 857          */
 858         return new CollectorImpl<>(
 859                 () -> new double[4],
 860                 (a, t) -> { double val = mapper.applyAsDouble(t); sumWithCompensation(a, val); a[2]++; a[3]+= val;},
 861                 (a, b) -> { sumWithCompensation(a, b[0]); sumWithCompensation(a, b[1]); a[2] += b[2]; a[3] += b[3]; return a; },
 862                 a -> (a[2] == 0) ? 0.0d : (computeFinalSum(a) / a[2]),
 863                 CH_NOID);
 864     }
 865 
 866     /**
 867      * Returns a {@code Collector} which performs a reduction of its
 868      * input elements under a specified {@code BinaryOperator} using the
 869      * provided identity.
 870      *
 871      * @apiNote
 872      * The {@code reducing()} collectors are most useful when used in a
 873      * multi-level reduction, downstream of {@code groupingBy} or
 874      * {@code partitioningBy}.  To perform a simple reduction on a stream,
 875      * use {@link Stream#reduce(Object, BinaryOperator)}} instead.
 876      *
 877      * @param <T> element type for the input and output of the reduction
 878      * @param identity the identity value for the reduction (also, the value
 879      *                 that is returned when there are no input elements)
 880      * @param op a {@code BinaryOperator<T>} used to reduce the input elements
 881      * @return a {@code Collector} which implements the reduction operation
 882      *
 883      * @see #reducing(BinaryOperator)
 884      * @see #reducing(Object, Function, BinaryOperator)
 885      */
 886     public static <T> Collector<T, ?, T>
 887     reducing(T identity, BinaryOperator<T> op) {
 888         return new CollectorImpl<>(
 889                 boxSupplier(identity),
 890                 (a, t) -> { a[0] = op.apply(a[0], t); },
 891                 (a, b) -> { a[0] = op.apply(a[0], b[0]); return a; },
 892                 a -> a[0],
 893                 CH_NOID);
 894     }
 895 
 896     @SuppressWarnings("unchecked")
 897     private static <T> Supplier<T[]> boxSupplier(T identity) {
 898         return () -> (T[]) new Object[] { identity };
 899     }
 900 
 901     /**
 902      * Returns a {@code Collector} which performs a reduction of its
 903      * input elements under a specified {@code BinaryOperator}.  The result
 904      * is described as an {@code Optional<T>}.
 905      *
 906      * @apiNote
 907      * The {@code reducing()} collectors are most useful when used in a
 908      * multi-level reduction, downstream of {@code groupingBy} or
 909      * {@code partitioningBy}.  To perform a simple reduction on a stream,
 910      * use {@link Stream#reduce(BinaryOperator)} instead.
 911      *
 912      * <p>For example, given a stream of {@code Person}, to calculate tallest
 913      * person in each city:
 914      * <pre>{@code
 915      * Comparator<Person> byHeight = Comparator.comparing(Person::getHeight);
 916      * Map<City, Optional<Person>> tallestByCity
 917      *   = people.stream().collect(
 918      *     groupingBy(Person::getCity,
 919      *                reducing(BinaryOperator.maxBy(byHeight))));
 920      * }</pre>
 921      *
 922      * @param <T> element type for the input and output of the reduction
 923      * @param op a {@code BinaryOperator<T>} used to reduce the input elements
 924      * @return a {@code Collector} which implements the reduction operation
 925      *
 926      * @see #reducing(Object, BinaryOperator)
 927      * @see #reducing(Object, Function, BinaryOperator)
 928      */
 929     public static <T> Collector<T, ?, Optional<T>>
 930     reducing(BinaryOperator<T> op) {
 931         class OptionalBox implements Consumer<T> {
 932             T value = null;
 933             boolean present = false;
 934 
 935             @Override
 936             public void accept(T t) {
 937                 if (present) {
 938                     value = op.apply(value, t);
 939                 }
 940                 else {
 941                     value = t;
 942                     present = true;
 943                 }
 944             }
 945         }
 946 
 947         return new CollectorImpl<T, OptionalBox, Optional<T>>(
 948                 OptionalBox::new, OptionalBox::accept,
 949                 (a, b) -> { if (b.present) a.accept(b.value); return a; },
 950                 a -> Optional.ofNullable(a.value), CH_NOID);
 951     }
 952 
 953     /**
 954      * Returns a {@code Collector} which performs a reduction of its
 955      * input elements under a specified mapping function and
 956      * {@code BinaryOperator}. This is a generalization of
 957      * {@link #reducing(Object, BinaryOperator)} which allows a transformation
 958      * of the elements before reduction.
 959      *
 960      * @apiNote
 961      * The {@code reducing()} collectors are most useful when used in a
 962      * multi-level reduction, downstream of {@code groupingBy} or
 963      * {@code partitioningBy}.  To perform a simple map-reduce on a stream,
 964      * use {@link Stream#map(Function)} and {@link Stream#reduce(Object, BinaryOperator)}
 965      * instead.
 966      *
 967      * <p>For example, given a stream of {@code Person}, to calculate the longest
 968      * last name of residents in each city:
 969      * <pre>{@code
 970      * Comparator<String> byLength = Comparator.comparing(String::length);
 971      * Map<City, String> longestLastNameByCity
 972      *   = people.stream().collect(
 973      *     groupingBy(Person::getCity,
 974      *                reducing("",
 975      *                         Person::getLastName,
 976      *                         BinaryOperator.maxBy(byLength))));
 977      * }</pre>
 978      *
 979      * @param <T> the type of the input elements
 980      * @param <U> the type of the mapped values
 981      * @param identity the identity value for the reduction (also, the value
 982      *                 that is returned when there are no input elements)
 983      * @param mapper a mapping function to apply to each input value
 984      * @param op a {@code BinaryOperator<U>} used to reduce the mapped values
 985      * @return a {@code Collector} implementing the map-reduce operation
 986      *
 987      * @see #reducing(Object, BinaryOperator)
 988      * @see #reducing(BinaryOperator)
 989      */
 990     public static <T, U>
 991     Collector<T, ?, U> reducing(U identity,
 992                                 Function<? super T, ? extends U> mapper,
 993                                 BinaryOperator<U> op) {
 994         return new CollectorImpl<>(
 995                 boxSupplier(identity),
 996                 (a, t) -> { a[0] = op.apply(a[0], mapper.apply(t)); },
 997                 (a, b) -> { a[0] = op.apply(a[0], b[0]); return a; },
 998                 a -> a[0], CH_NOID);
 999     }
1000 
1001     /**
1002      * Returns a {@code Collector} implementing a "group by" operation on
1003      * input elements of type {@code T}, grouping elements according to a
1004      * classification function, and returning the results in a {@code Map}.
1005      *
1006      * <p>The classification function maps elements to some key type {@code K}.
1007      * The collector produces a {@code Map<K, List<T>>} whose keys are the
1008      * values resulting from applying the classification function to the input
1009      * elements, and whose corresponding values are {@code List}s containing the
1010      * input elements which map to the associated key under the classification
1011      * function.
1012      *
1013      * <p>There are no guarantees on the type, mutability, serializability, or
1014      * thread-safety of the {@code Map} or {@code List} objects returned.
1015      * @implSpec
1016      * This produces a result similar to:
1017      * <pre>{@code
1018      *     groupingBy(classifier, toList());
1019      * }</pre>
1020      *
1021      * @implNote
1022      * The returned {@code Collector} is not concurrent.  For parallel stream
1023      * pipelines, the {@code combiner} function operates by merging the keys
1024      * from one map into another, which can be an expensive operation.  If
1025      * preservation of the order in which elements appear in the resulting {@code Map}
1026      * collector is not required, using {@link #groupingByConcurrent(Function)}
1027      * may offer better parallel performance.
1028      *
1029      * @param <T> the type of the input elements
1030      * @param <K> the type of the keys
1031      * @param classifier the classifier function mapping input elements to keys
1032      * @return a {@code Collector} implementing the group-by operation
1033      *
1034      * @see #groupingBy(Function, Collector)
1035      * @see #groupingBy(Function, Supplier, Collector)
1036      * @see #groupingByConcurrent(Function)
1037      */
1038     public static <T, K> Collector<T, ?, Map<K, List<T>>>
1039     groupingBy(Function<? super T, ? extends K> classifier) {
1040         return groupingBy(classifier, toList());
1041     }
1042 
1043     /**
1044      * Returns a {@code Collector} implementing a cascaded "group by" operation
1045      * on input elements of type {@code T}, grouping elements according to a
1046      * classification function, and then performing a reduction operation on
1047      * the values associated with a given key using the specified downstream
1048      * {@code Collector}.
1049      *
1050      * <p>The classification function maps elements to some key type {@code K}.
1051      * The downstream collector operates on elements of type {@code T} and
1052      * produces a result of type {@code D}. The resulting collector produces a
1053      * {@code Map<K, D>}.
1054      *
1055      * <p>There are no guarantees on the type, mutability,
1056      * serializability, or thread-safety of the {@code Map} returned.
1057      *
1058      * <p>For example, to compute the set of last names of people in each city:
1059      * <pre>{@code
1060      * Map<City, Set<String>> namesByCity
1061      *   = people.stream().collect(
1062      *     groupingBy(Person::getCity,
1063      *                mapping(Person::getLastName,
1064      *                        toSet())));
1065      * }</pre>
1066      *
1067      * @implNote
1068      * The returned {@code Collector} is not concurrent.  For parallel stream
1069      * pipelines, the {@code combiner} function operates by merging the keys
1070      * from one map into another, which can be an expensive operation.  If
1071      * preservation of the order in which elements are presented to the downstream
1072      * collector is not required, using {@link #groupingByConcurrent(Function, Collector)}
1073      * may offer better parallel performance.
1074      *
1075      * @param <T> the type of the input elements
1076      * @param <K> the type of the keys
1077      * @param <A> the intermediate accumulation type of the downstream collector
1078      * @param <D> the result type of the downstream reduction
1079      * @param classifier a classifier function mapping input elements to keys
1080      * @param downstream a {@code Collector} implementing the downstream reduction
1081      * @return a {@code Collector} implementing the cascaded group-by operation
1082      * @see #groupingBy(Function)
1083      *
1084      * @see #groupingBy(Function, Supplier, Collector)
1085      * @see #groupingByConcurrent(Function, Collector)
1086      */
1087     public static <T, K, A, D>
1088     Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,
1089                                           Collector<? super T, A, D> downstream) {
1090         return groupingBy(classifier, HashMap::new, downstream);
1091     }
1092 
1093     /**
1094      * Returns a {@code Collector} implementing a cascaded "group by" operation
1095      * on input elements of type {@code T}, grouping elements according to a
1096      * classification function, and then performing a reduction operation on
1097      * the values associated with a given key using the specified downstream
1098      * {@code Collector}.  The {@code Map} produced by the Collector is created
1099      * with the supplied factory function.
1100      *
1101      * <p>The classification function maps elements to some key type {@code K}.
1102      * The downstream collector operates on elements of type {@code T} and
1103      * produces a result of type {@code D}. The resulting collector produces a
1104      * {@code Map<K, D>}.
1105      *
1106      * <p>For example, to compute the set of last names of people in each city,
1107      * where the city names are sorted:
1108      * <pre>{@code
1109      * Map<City, Set<String>> namesByCity
1110      *   = people.stream().collect(
1111      *     groupingBy(Person::getCity,
1112      *                TreeMap::new,
1113      *                mapping(Person::getLastName,
1114      *                        toSet())));
1115      * }</pre>
1116      *
1117      * @implNote
1118      * The returned {@code Collector} is not concurrent.  For parallel stream
1119      * pipelines, the {@code combiner} function operates by merging the keys
1120      * from one map into another, which can be an expensive operation.  If
1121      * preservation of the order in which elements are presented to the downstream
1122      * collector is not required, using {@link #groupingByConcurrent(Function, Supplier, Collector)}
1123      * may offer better parallel performance.
1124      *
1125      * @param <T> the type of the input elements
1126      * @param <K> the type of the keys
1127      * @param <A> the intermediate accumulation type of the downstream collector
1128      * @param <D> the result type of the downstream reduction
1129      * @param <M> the type of the resulting {@code Map}
1130      * @param classifier a classifier function mapping input elements to keys
1131      * @param downstream a {@code Collector} implementing the downstream reduction
1132      * @param mapFactory a supplier providing a new empty {@code Map}
1133      *                   into which the results will be inserted
1134      * @return a {@code Collector} implementing the cascaded group-by operation
1135      *
1136      * @see #groupingBy(Function, Collector)
1137      * @see #groupingBy(Function)
1138      * @see #groupingByConcurrent(Function, Supplier, Collector)
1139      */
1140     public static <T, K, D, A, M extends Map<K, D>>
1141     Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier,
1142                                   Supplier<M> mapFactory,
1143                                   Collector<? super T, A, D> downstream) {
1144         Supplier<A> downstreamSupplier = downstream.supplier();
1145         BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
1146         BiConsumer<Map<K, A>, T> accumulator = (m, t) -> {
1147             K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
1148             A container = m.computeIfAbsent(key, k -> downstreamSupplier.get());
1149             downstreamAccumulator.accept(container, t);
1150         };
1151         BinaryOperator<Map<K, A>> merger = Collectors.<K, A, Map<K, A>>mapMerger(downstream.combiner());
1152         @SuppressWarnings("unchecked")
1153         Supplier<Map<K, A>> mangledFactory = (Supplier<Map<K, A>>) mapFactory;
1154 
1155         if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
1156             return new CollectorImpl<>(mangledFactory, accumulator, merger, CH_ID);
1157         }
1158         else {
1159             @SuppressWarnings("unchecked")
1160             Function<A, A> downstreamFinisher = (Function<A, A>) downstream.finisher();
1161             Function<Map<K, A>, M> finisher = intermediate -> {
1162                 intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v));
1163                 @SuppressWarnings("unchecked")
1164                 M castResult = (M) intermediate;
1165                 return castResult;
1166             };
1167             return new CollectorImpl<>(mangledFactory, accumulator, merger, finisher, CH_NOID);
1168         }
1169     }
1170 
1171     /**
1172      * Returns a concurrent {@code Collector} implementing a "group by"
1173      * operation on input elements of type {@code T}, grouping elements
1174      * according to a classification function.
1175      *
1176      * <p>This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
1177      * {@link Collector.Characteristics#UNORDERED unordered} Collector.
1178      *
1179      * <p>The classification function maps elements to some key type {@code K}.
1180      * The collector produces a {@code ConcurrentMap<K, List<T>>} whose keys are the
1181      * values resulting from applying the classification function to the input
1182      * elements, and whose corresponding values are {@code List}s containing the
1183      * input elements which map to the associated key under the classification
1184      * function.
1185      *
1186      * <p>There are no guarantees on the type, mutability, or serializability
1187      * of the {@code ConcurrentMap} or {@code List} objects returned, or of the
1188      * thread-safety of the {@code List} objects returned.
1189      * @implSpec
1190      * This produces a result similar to:
1191      * <pre>{@code
1192      *     groupingByConcurrent(classifier, toList());
1193      * }</pre>
1194      *
1195      * @param <T> the type of the input elements
1196      * @param <K> the type of the keys
1197      * @param classifier a classifier function mapping input elements to keys
1198      * @return a concurrent, unordered {@code Collector} implementing the group-by operation
1199      *
1200      * @see #groupingBy(Function)
1201      * @see #groupingByConcurrent(Function, Collector)
1202      * @see #groupingByConcurrent(Function, Supplier, Collector)
1203      */
1204     public static <T, K>
1205     Collector<T, ?, ConcurrentMap<K, List<T>>>
1206     groupingByConcurrent(Function<? super T, ? extends K> classifier) {
1207         return groupingByConcurrent(classifier, ConcurrentHashMap::new, toList());
1208     }
1209 
1210     /**
1211      * Returns a concurrent {@code Collector} implementing a cascaded "group by"
1212      * operation on input elements of type {@code T}, grouping elements
1213      * according to a classification function, and then performing a reduction
1214      * operation on the values associated with a given key using the specified
1215      * downstream {@code Collector}.
1216      *
1217      * <p>This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
1218      * {@link Collector.Characteristics#UNORDERED unordered} Collector.
1219      *
1220      * <p>The classification function maps elements to some key type {@code K}.
1221      * The downstream collector operates on elements of type {@code T} and
1222      * produces a result of type {@code D}. The resulting collector produces a
1223      * {@code ConcurrentMap<K, D>}.
1224      *
1225      * <p>There are no guarantees on the type, mutability, or serializability
1226      * of the {@code ConcurrentMap} returned.
1227      *
1228      * <p>For example, to compute the set of last names of people in each city,
1229      * where the city names are sorted:
1230      * <pre>{@code
1231      * ConcurrentMap<City, Set<String>> namesByCity
1232      *   = people.stream().collect(
1233      *     groupingByConcurrent(Person::getCity,
1234      *                          mapping(Person::getLastName,
1235      *                                  toSet())));
1236      * }</pre>
1237      *
1238      * @param <T> the type of the input elements
1239      * @param <K> the type of the keys
1240      * @param <A> the intermediate accumulation type of the downstream collector
1241      * @param <D> the result type of the downstream reduction
1242      * @param classifier a classifier function mapping input elements to keys
1243      * @param downstream a {@code Collector} implementing the downstream reduction
1244      * @return a concurrent, unordered {@code Collector} implementing the cascaded group-by operation
1245      *
1246      * @see #groupingBy(Function, Collector)
1247      * @see #groupingByConcurrent(Function)
1248      * @see #groupingByConcurrent(Function, Supplier, Collector)
1249      */
1250     public static <T, K, A, D>
1251     Collector<T, ?, ConcurrentMap<K, D>> groupingByConcurrent(Function<? super T, ? extends K> classifier,
1252                                                               Collector<? super T, A, D> downstream) {
1253         return groupingByConcurrent(classifier, ConcurrentHashMap::new, downstream);
1254     }
1255 
1256     /**
1257      * Returns a concurrent {@code Collector} implementing a cascaded "group by"
1258      * operation on input elements of type {@code T}, grouping elements
1259      * according to a classification function, and then performing a reduction
1260      * operation on the values associated with a given key using the specified
1261      * downstream {@code Collector}.  The {@code ConcurrentMap} produced by the
1262      * Collector is created with the supplied factory function.
1263      *
1264      * <p>This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
1265      * {@link Collector.Characteristics#UNORDERED unordered} Collector.
1266      *
1267      * <p>The classification function maps elements to some key type {@code K}.
1268      * The downstream collector operates on elements of type {@code T} and
1269      * produces a result of type {@code D}. The resulting collector produces a
1270      * {@code ConcurrentMap<K, D>}.
1271      *
1272      * <p>For example, to compute the set of last names of people in each city,
1273      * where the city names are sorted:
1274      * <pre>{@code
1275      * ConcurrentMap<City, Set<String>> namesByCity
1276      *   = people.stream().collect(
1277      *     groupingByConcurrent(Person::getCity,
1278      *                          ConcurrentSkipListMap::new,
1279      *                          mapping(Person::getLastName,
1280      *                                  toSet())));
1281      * }</pre>
1282      *
1283      * @param <T> the type of the input elements
1284      * @param <K> the type of the keys
1285      * @param <A> the intermediate accumulation type of the downstream collector
1286      * @param <D> the result type of the downstream reduction
1287      * @param <M> the type of the resulting {@code ConcurrentMap}
1288      * @param classifier a classifier function mapping input elements to keys
1289      * @param downstream a {@code Collector} implementing the downstream reduction
1290      * @param mapFactory a supplier providing a new empty {@code ConcurrentMap}
1291      *                   into which the results will be inserted
1292      * @return a concurrent, unordered {@code Collector} implementing the cascaded group-by operation
1293      *
1294      * @see #groupingByConcurrent(Function)
1295      * @see #groupingByConcurrent(Function, Collector)
1296      * @see #groupingBy(Function, Supplier, Collector)
1297      */
1298     public static <T, K, A, D, M extends ConcurrentMap<K, D>>
1299     Collector<T, ?, M> groupingByConcurrent(Function<? super T, ? extends K> classifier,
1300                                             Supplier<M> mapFactory,
1301                                             Collector<? super T, A, D> downstream) {
1302         Supplier<A> downstreamSupplier = downstream.supplier();
1303         BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
1304         BinaryOperator<ConcurrentMap<K, A>> merger = Collectors.<K, A, ConcurrentMap<K, A>>mapMerger(downstream.combiner());
1305         @SuppressWarnings("unchecked")
1306         Supplier<ConcurrentMap<K, A>> mangledFactory = (Supplier<ConcurrentMap<K, A>>) mapFactory;
1307         BiConsumer<ConcurrentMap<K, A>, T> accumulator;
1308         if (downstream.characteristics().contains(Collector.Characteristics.CONCURRENT)) {
1309             accumulator = (m, t) -> {
1310                 K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
1311                 A resultContainer = m.computeIfAbsent(key, k -> downstreamSupplier.get());
1312                 downstreamAccumulator.accept(resultContainer, t);
1313             };
1314         }
1315         else {
1316             accumulator = (m, t) -> {
1317                 K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
1318                 A resultContainer = m.computeIfAbsent(key, k -> downstreamSupplier.get());
1319                 synchronized (resultContainer) {
1320                     downstreamAccumulator.accept(resultContainer, t);
1321                 }
1322             };
1323         }
1324 
1325         if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
1326             return new CollectorImpl<>(mangledFactory, accumulator, merger, CH_CONCURRENT_ID);
1327         }
1328         else {
1329             @SuppressWarnings("unchecked")
1330             Function<A, A> downstreamFinisher = (Function<A, A>) downstream.finisher();
1331             Function<ConcurrentMap<K, A>, M> finisher = intermediate -> {
1332                 intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v));
1333                 @SuppressWarnings("unchecked")
1334                 M castResult = (M) intermediate;
1335                 return castResult;
1336             };
1337             return new CollectorImpl<>(mangledFactory, accumulator, merger, finisher, CH_CONCURRENT_NOID);
1338         }
1339     }
1340 
1341     /**
1342      * Returns a {@code Collector} which partitions the input elements according
1343      * to a {@code Predicate}, and organizes them into a
1344      * {@code Map<Boolean, List<T>>}.
1345      *
1346      * The returned {@code Map} always contains mappings for both
1347      * {@code false} and {@code true} keys.
1348      * There are no guarantees on the type, mutability,
1349      * serializability, or thread-safety of the {@code Map} or {@code List}
1350      * returned.
1351      *
1352      * @apiNote
1353      * If a partition has no elements, its value in the result Map will be
1354      * an empty List.
1355      *
1356      * @param <T> the type of the input elements
1357      * @param predicate a predicate used for classifying input elements
1358      * @return a {@code Collector} implementing the partitioning operation
1359      *
1360      * @see #partitioningBy(Predicate, Collector)
1361      */
1362     public static <T>
1363     Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate) {
1364         return partitioningBy(predicate, toList());
1365     }
1366 
1367     /**
1368      * Returns a {@code Collector} which partitions the input elements according
1369      * to a {@code Predicate}, reduces the values in each partition according to
1370      * another {@code Collector}, and organizes them into a
1371      * {@code Map<Boolean, D>} whose values are the result of the downstream
1372      * reduction.
1373      *
1374      * <p>
1375      * The returned {@code Map} always contains mappings for both
1376      * {@code false} and {@code true} keys.
1377      * There are no guarantees on the type, mutability,
1378      * serializability, or thread-safety of the {@code Map} returned.
1379      *
1380      * @apiNote
1381      * If a partition has no elements, its value in the result Map will be
1382      * obtained by calling the downstream collector's supplier function and then
1383      * applying the finisher function.
1384      *
1385      * @param <T> the type of the input elements
1386      * @param <A> the intermediate accumulation type of the downstream collector
1387      * @param <D> the result type of the downstream reduction
1388      * @param predicate a predicate used for classifying input elements
1389      * @param downstream a {@code Collector} implementing the downstream
1390      *                   reduction
1391      * @return a {@code Collector} implementing the cascaded partitioning
1392      *         operation
1393      *
1394      * @see #partitioningBy(Predicate)
1395      */
1396     public static <T, D, A>
1397     Collector<T, ?, Map<Boolean, D>> partitioningBy(Predicate<? super T> predicate,
1398                                                     Collector<? super T, A, D> downstream) {
1399         BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
1400         BiConsumer<Partition<A>, T> accumulator = (result, t) ->
1401                 downstreamAccumulator.accept(predicate.test(t) ? result.forTrue : result.forFalse, t);
1402         BinaryOperator<A> op = downstream.combiner();
1403         BinaryOperator<Partition<A>> merger = (left, right) ->
1404                 new Partition<>(op.apply(left.forTrue, right.forTrue),
1405                                 op.apply(left.forFalse, right.forFalse));
1406         Supplier<Partition<A>> supplier = () ->
1407                 new Partition<>(downstream.supplier().get(),
1408                                 downstream.supplier().get());
1409         if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
1410             return new CollectorImpl<>(supplier, accumulator, merger, CH_ID);
1411         }
1412         else {
1413             Function<Partition<A>, Map<Boolean, D>> finisher = par ->
1414                     new Partition<>(downstream.finisher().apply(par.forTrue),
1415                                     downstream.finisher().apply(par.forFalse));
1416             return new CollectorImpl<>(supplier, accumulator, merger, finisher, CH_NOID);
1417         }
1418     }
1419 
1420     /**
1421      * Returns a {@code Collector} that accumulates elements into a
1422      * {@code Map} whose keys and values are the result of applying the provided
1423      * mapping functions to the input elements.
1424      *
1425      * <p>If the mapped keys contain duplicates (according to
1426      * {@link Object#equals(Object)}), an {@code IllegalStateException} is
1427      * thrown when the collection operation is performed.  If the mapped keys
1428      * might have duplicates, use {@link #toMap(Function, Function, BinaryOperator)}
1429      * instead.
1430      *
1431      * <p>There are no guarantees on the type, mutability, serializability,
1432      * or thread-safety of the {@code Map} returned.
1433      *
1434      * @apiNote
1435      * It is common for either the key or the value to be the input elements.
1436      * In this case, the utility method
1437      * {@link java.util.function.Function#identity()} may be helpful.
1438      * For example, the following produces a {@code Map} mapping
1439      * students to their grade point average:
1440      * <pre>{@code
1441      * Map<Student, Double> studentToGPA
1442      *   = students.stream().collect(
1443      *     toMap(Function.identity(),
1444      *           student -> computeGPA(student)));
1445      * }</pre>
1446      * And the following produces a {@code Map} mapping a unique identifier to
1447      * students:
1448      * <pre>{@code
1449      * Map<String, Student> studentIdToStudent
1450      *   = students.stream().collect(
1451      *     toMap(Student::getId,
1452      *           Function.identity()));
1453      * }</pre>
1454      *
1455      * @implNote
1456      * The returned {@code Collector} is not concurrent.  For parallel stream
1457      * pipelines, the {@code combiner} function operates by merging the keys
1458      * from one map into another, which can be an expensive operation.  If it is
1459      * not required that results are inserted into the {@code Map} in encounter
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<>(size -> new HashMap<>((int) Math.ceil(size / .75), .75f),
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      *
1501      * @param <T> the type of the input elements
1502      * @param <K> the output type of the key mapping function
1503      * @param <U> the output type of the value mapping function
1504      * @param keyMapper a mapping function to produce keys, must be non-null
1505      * @param valueMapper a mapping function to produce values, must be non-null
1506      * @return a {@code Collector} that accumulates the input elements into an
1507      * <a href="../Map.html#unmodifiable">unmodifiable Map</a>, whose keys and values
1508      * are the result of applying the provided mapping functions to the input elements
1509      * @throws NullPointerException if either keyMapper or valueMapper is null
1510      *
1511      * @see #toUnmodifiableMap(Function, Function, BinaryOperator)
1512      * @since 10
1513      */
1514     @SuppressWarnings({"rawtypes", "unchecked"})
1515     public static <T, K, U>
1516     Collector<T, ?, Map<K,U>> toUnmodifiableMap(Function<? super T, ? extends K> keyMapper,
1517                                                 Function<? super T, ? extends U> valueMapper) {
1518         Objects.requireNonNull(keyMapper, "keyMapper");
1519         Objects.requireNonNull(valueMapper, "valueMapper");
1520         return collectingAndThen(
1521                 toMap(keyMapper, valueMapper),
1522                 map -> (Map<K,U>)Map.ofEntries(map.entrySet().toArray(new Map.Entry[0])));
1523     }
1524 
1525     /**
1526      * Returns a {@code Collector} that accumulates elements into a
1527      * {@code Map} whose keys and values are the result of applying the provided
1528      * mapping functions to the input elements.
1529      *
1530      * <p>If the mapped
1531      * keys contain duplicates (according to {@link Object#equals(Object)}),
1532      * the value mapping function is applied to each equal element, and the
1533      * results are merged using the provided merging function.
1534      *
1535      * <p>There are no guarantees on the type, mutability, serializability,
1536      * or thread-safety of the {@code Map} returned.
1537      *
1538      * @apiNote
1539      * There are multiple ways to deal with collisions between multiple elements
1540      * mapping to the same key.  The other forms of {@code toMap} simply use
1541      * a merge function that throws unconditionally, but you can easily write
1542      * more flexible merge policies.  For example, if you have a stream
1543      * of {@code Person}, and you want to produce a "phone book" mapping name to
1544      * address, but it is possible that two persons have the same name, you can
1545      * do as follows to gracefully deal with these collisions, and produce a
1546      * {@code Map} mapping names to a concatenated list of addresses:
1547      * <pre>{@code
1548      * Map<String, String> phoneBook
1549      *   = people.stream().collect(
1550      *     toMap(Person::getName,
1551      *           Person::getAddress,
1552      *           (s, a) -> s + ", " + a));
1553      * }</pre>
1554      *
1555      * @implNote
1556      * The returned {@code Collector} is not concurrent.  For parallel stream
1557      * pipelines, the {@code combiner} function operates by merging the keys
1558      * from one map into another, which can be an expensive operation.  If it is
1559      * not required that results are merged into the {@code Map} in encounter
1560      * order, using {@link #toConcurrentMap(Function, Function, BinaryOperator)}
1561      * may offer better parallel performance.
1562      *
1563      * @param <T> the type of the input elements
1564      * @param <K> the output type of the key mapping function
1565      * @param <U> the output type of the value mapping function
1566      * @param keyMapper a mapping function to produce keys
1567      * @param valueMapper a mapping function to produce values
1568      * @param mergeFunction a merge function, used to resolve collisions between
1569      *                      values associated with the same key, as supplied
1570      *                      to {@link Map#merge(Object, Object, BiFunction)}
1571      * @return a {@code Collector} which collects elements into a {@code Map}
1572      * whose keys are the result of applying a key mapping function to the input
1573      * elements, and whose values are the result of applying a value mapping
1574      * function to all input elements equal to the key and combining them
1575      * using the merge function
1576      *
1577      * @see #toMap(Function, Function)
1578      * @see #toMap(Function, Function, BinaryOperator, Supplier)
1579      * @see #toConcurrentMap(Function, Function, BinaryOperator)
1580      */
1581     public static <T, K, U>
1582     Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
1583                                     Function<? super T, ? extends U> valueMapper,
1584                                     BinaryOperator<U> mergeFunction) {
1585         return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
1586     }
1587 
1588 
1589     /**
1590      * Returns a {@code Collector} that accumulates the input elements into an
1591      * <a href="../Map.html#unmodifiable">unmodifiable Map</a>,
1592      * whose keys and values are the result of applying the provided
1593      * mapping functions to the input elements.
1594      *
1595      * <p>If the mapped
1596      * keys contain duplicates (according to {@link Object#equals(Object)}),
1597      * the value mapping function is applied to each equal element, and the
1598      * results are merged using the provided merging function.
1599      *
1600      * <p>The returned Collector disallows null keys and values. If either mapping function
1601      * returns null, {@code NullPointerException} will be thrown.
1602      *
1603      * @param <T> the type of the input elements
1604      * @param <K> the output type of the key mapping function
1605      * @param <U> the output type of the value mapping function
1606      * @param keyMapper a mapping function to produce keys, must be non-null
1607      * @param valueMapper a mapping function to produce values, must be non-null
1608      * @param mergeFunction a merge function, used to resolve collisions between
1609      *                      values associated with the same key, as supplied
1610      *                      to {@link Map#merge(Object, Object, BiFunction)},
1611      *                      must be non-null
1612      * @return a {@code Collector} that accumulates the input elements into an
1613      * <a href="../Map.html#unmodifiable">unmodifiable Map</a>, whose keys and values
1614      * are the result of applying the provided mapping functions to the input elements
1615      * @throws NullPointerException if the keyMapper, valueMapper, or mergeFunction is null
1616      *
1617      * @see #toUnmodifiableMap(Function, Function)
1618      * @since 10
1619      */
1620     @SuppressWarnings({"rawtypes", "unchecked"})
1621     public static <T, K, U>
1622     Collector<T, ?, Map<K,U>> toUnmodifiableMap(Function<? super T, ? extends K> keyMapper,
1623                                                 Function<? super T, ? extends U> valueMapper,
1624                                                 BinaryOperator<U> mergeFunction) {
1625         Objects.requireNonNull(keyMapper, "keyMapper");
1626         Objects.requireNonNull(valueMapper, "valueMapper");
1627         Objects.requireNonNull(mergeFunction, "mergeFunction");
1628         return collectingAndThen(
1629                 toMap(keyMapper, valueMapper, mergeFunction, HashMap::new),
1630                 map -> (Map<K,U>)Map.ofEntries(map.entrySet().toArray(new Map.Entry[0])));
1631     }
1632 
1633     /**
1634      * Returns a {@code Collector} that accumulates elements into a
1635      * {@code Map} whose keys and values are the result of applying the provided
1636      * mapping functions to the input elements.
1637      *
1638      * <p>If the mapped
1639      * keys contain duplicates (according to {@link Object#equals(Object)}),
1640      * the value mapping function is applied to each equal element, and the
1641      * results are merged using the provided merging function.  The {@code Map}
1642      * is created by a provided supplier function.
1643      *
1644      * @implNote
1645      * The returned {@code Collector} is not concurrent.  For parallel stream
1646      * pipelines, the {@code combiner} function operates by merging the keys
1647      * from one map into another, which can be an expensive operation.  If it is
1648      * not required that results are merged into the {@code Map} in encounter
1649      * order, using {@link #toConcurrentMap(Function, Function, BinaryOperator, Supplier)}
1650      * may offer better parallel performance.
1651      *
1652      * @param <T> the type of the input elements
1653      * @param <K> the output type of the key mapping function
1654      * @param <U> the output type of the value mapping function
1655      * @param <M> the type of the resulting {@code Map}
1656      * @param keyMapper a mapping function to produce keys
1657      * @param valueMapper a mapping function to produce values
1658      * @param mergeFunction a merge function, used to resolve collisions between
1659      *                      values associated with the same key, as supplied
1660      *                      to {@link Map#merge(Object, Object, BiFunction)}
1661      * @param mapFactory a supplier providing a new empty {@code Map}
1662      *                   into which the results will be inserted
1663      * @return a {@code Collector} which collects elements into a {@code Map}
1664      * whose keys are the result of applying a key mapping function to the input
1665      * elements, and whose values are the result of applying a value mapping
1666      * function to all input elements equal to the key and combining them
1667      * using the merge function
1668      *
1669      * @see #toMap(Function, Function)
1670      * @see #toMap(Function, Function, BinaryOperator)
1671      * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
1672      */
1673     public static <T, K, U, M extends Map<K, U>>
1674     Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
1675                              Function<? super T, ? extends U> valueMapper,
1676                              BinaryOperator<U> mergeFunction,
1677                              Supplier<M> mapFactory) {
1678         BiConsumer<M, T> accumulator
1679                 = (map, element) -> map.merge(keyMapper.apply(element),
1680                                               valueMapper.apply(element), mergeFunction);
1681         return new CollectorImpl<>(mapFactory, accumulator, mapMerger(mergeFunction), CH_ID);
1682     }
1683 
1684     /**
1685      * Returns a concurrent {@code Collector} that accumulates elements into a
1686      * {@code ConcurrentMap} whose keys and values are the result of applying
1687      * the provided mapping functions to the input elements.
1688      *
1689      * <p>If the mapped keys contain duplicates (according to
1690      * {@link Object#equals(Object)}), an {@code IllegalStateException} is
1691      * thrown when the collection operation is performed.  If the mapped keys
1692      * may have duplicates, use
1693      * {@link #toConcurrentMap(Function, Function, BinaryOperator)} instead.
1694      *
1695      * <p>There are no guarantees on the type, mutability, or serializability
1696      * of the {@code ConcurrentMap} returned.
1697      *
1698      * @apiNote
1699      * It is common for either the key or the value to be the input elements.
1700      * In this case, the utility method
1701      * {@link java.util.function.Function#identity()} may be helpful.
1702      * For example, the following produces a {@code ConcurrentMap} mapping
1703      * students to their grade point average:
1704      * <pre>{@code
1705      * ConcurrentMap<Student, Double> studentToGPA
1706      *   = students.stream().collect(
1707      *     toConcurrentMap(Function.identity(),
1708      *                     student -> computeGPA(student)));
1709      * }</pre>
1710      * And the following produces a {@code ConcurrentMap} mapping a
1711      * unique identifier to students:
1712      * <pre>{@code
1713      * ConcurrentMap<String, Student> studentIdToStudent
1714      *   = students.stream().collect(
1715      *     toConcurrentMap(Student::getId,
1716      *                     Function.identity()));
1717      * }</pre>
1718      *
1719      * <p>This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
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<>(size -> new ConcurrentHashMap<>((int) Math.ceil(size / .75), .75f),
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
1761      * a merge function that throws unconditionally, but you can easily write
1762      * more flexible merge policies.  For example, if you have a stream
1763      * of {@code Person}, and you want to produce a "phone book" mapping name to
1764      * address, but it is possible that two persons have the same name, you can
1765      * do as follows to gracefully deal with these collisions, and produce a
1766      * {@code ConcurrentMap} mapping names to a concatenated list of addresses:
1767      * <pre>{@code
1768      * ConcurrentMap<String, String> phoneBook
1769      *   = people.stream().collect(
1770      *     toConcurrentMap(Person::getName,
1771      *                     Person::getAddress,
1772      *                     (s, a) -> s + ", " + a));
1773      * }</pre>
1774      *
1775      * <p>This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
1776      * {@link Collector.Characteristics#UNORDERED unordered} Collector.
1777      *
1778      * @param <T> the type of the input elements
1779      * @param <K> the output type of the key mapping function
1780      * @param <U> the output type of the value mapping function
1781      * @param keyMapper a mapping function to produce keys
1782      * @param valueMapper a mapping function to produce values
1783      * @param mergeFunction a merge function, used to resolve collisions between
1784      *                      values associated with the same key, as supplied
1785      *                      to {@link Map#merge(Object, Object, BiFunction)}
1786      * @return a concurrent, unordered {@code Collector} which collects elements into a
1787      * {@code ConcurrentMap} whose keys are the result of applying a key mapping
1788      * function to the input elements, and whose values are the result of
1789      * applying a value mapping function to all input elements equal to the key
1790      * and combining them using the merge function
1791      *
1792      * @see #toConcurrentMap(Function, Function)
1793      * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
1794      * @see #toMap(Function, Function, BinaryOperator)
1795      */
1796     public static <T, K, U>
1797     Collector<T, ?, ConcurrentMap<K,U>>
1798     toConcurrentMap(Function<? super T, ? extends K> keyMapper,
1799                     Function<? super T, ? extends U> valueMapper,
1800                     BinaryOperator<U> mergeFunction) {
1801         return toConcurrentMap(keyMapper, valueMapper, mergeFunction, ConcurrentHashMap::new);
1802     }
1803 
1804     /**
1805      * Returns a concurrent {@code Collector} that accumulates elements into a
1806      * {@code ConcurrentMap} whose keys and values are the result of applying
1807      * the provided mapping functions to the input elements.
1808      *
1809      * <p>If the mapped keys contain duplicates (according to {@link Object#equals(Object)}),
1810      * the value mapping function is applied to each equal element, and the
1811      * results are merged using the provided merging function.  The
1812      * {@code ConcurrentMap} is created by a provided supplier function.
1813      *
1814      * <p>This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
1815      * {@link Collector.Characteristics#UNORDERED unordered} Collector.
1816      *
1817      * @param <T> the type of the input elements
1818      * @param <K> the output type of the key mapping function
1819      * @param <U> the output type of the value mapping function
1820      * @param <M> the type of the resulting {@code ConcurrentMap}
1821      * @param keyMapper a mapping function to produce keys
1822      * @param valueMapper a mapping function to produce values
1823      * @param mergeFunction a merge function, used to resolve collisions between
1824      *                      values associated with the same key, as supplied
1825      *                      to {@link Map#merge(Object, Object, BiFunction)}
1826      * @param mapFactory a supplier providing a new empty {@code ConcurrentMap}
1827      *                   into which the results will be inserted
1828      * @return a concurrent, unordered {@code Collector} which collects elements into a
1829      * {@code ConcurrentMap} whose keys are the result of applying a key mapping
1830      * function to the input elements, and whose values are the result of
1831      * applying a value mapping function to all input elements equal to the key
1832      * and combining them using the merge function
1833      *
1834      * @see #toConcurrentMap(Function, Function)
1835      * @see #toConcurrentMap(Function, Function, BinaryOperator)
1836      * @see #toMap(Function, Function, BinaryOperator, Supplier)
1837      */
1838     public static <T, K, U, M extends ConcurrentMap<K, U>>
1839     Collector<T, ?, M> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
1840                                        Function<? super T, ? extends U> valueMapper,
1841                                        BinaryOperator<U> mergeFunction,
1842                                        Supplier<M> mapFactory) {
1843         BiConsumer<M, T> accumulator
1844                 = (map, element) -> map.merge(keyMapper.apply(element),
1845                                               valueMapper.apply(element), mergeFunction);
1846         return new CollectorImpl<>(mapFactory, accumulator, mapMerger(mergeFunction), CH_CONCURRENT_ID);
1847     }
1848 
1849     /**
1850      * Returns a {@code Collector} which applies an {@code int}-producing
1851      * mapping function to each input element, and returns summary statistics
1852      * for the resulting values.
1853      *
1854      * @param <T> the type of the input elements
1855      * @param mapper a mapping function to apply to each element
1856      * @return a {@code Collector} implementing the summary-statistics reduction
1857      *
1858      * @see #summarizingDouble(ToDoubleFunction)
1859      * @see #summarizingLong(ToLongFunction)
1860      */
1861     public static <T>
1862     Collector<T, ?, IntSummaryStatistics> summarizingInt(ToIntFunction<? super T> mapper) {
1863         return new CollectorImpl<T, IntSummaryStatistics, IntSummaryStatistics>(
1864                 IntSummaryStatistics::new,
1865                 (r, t) -> r.accept(mapper.applyAsInt(t)),
1866                 (l, r) -> { l.combine(r); return l; }, CH_ID);
1867     }
1868 
1869     /**
1870      * Returns a {@code Collector} which applies an {@code long}-producing
1871      * mapping function to each input element, and returns summary statistics
1872      * for the resulting values.
1873      *
1874      * @param <T> the type of the input elements
1875      * @param mapper the mapping function to apply to each element
1876      * @return a {@code Collector} implementing the summary-statistics reduction
1877      *
1878      * @see #summarizingDouble(ToDoubleFunction)
1879      * @see #summarizingInt(ToIntFunction)
1880      */
1881     public static <T>
1882     Collector<T, ?, LongSummaryStatistics> summarizingLong(ToLongFunction<? super T> mapper) {
1883         return new CollectorImpl<T, LongSummaryStatistics, LongSummaryStatistics>(
1884                 LongSummaryStatistics::new,
1885                 (r, t) -> r.accept(mapper.applyAsLong(t)),
1886                 (l, r) -> { l.combine(r); return l; }, CH_ID);
1887     }
1888 
1889     /**
1890      * Returns a {@code Collector} which applies an {@code double}-producing
1891      * mapping function to each input element, and returns summary statistics
1892      * for the resulting values.
1893      *
1894      * @param <T> the type of the input elements
1895      * @param mapper a mapping function to apply to each element
1896      * @return a {@code Collector} implementing the summary-statistics reduction
1897      *
1898      * @see #summarizingLong(ToLongFunction)
1899      * @see #summarizingInt(ToIntFunction)
1900      */
1901     public static <T>
1902     Collector<T, ?, DoubleSummaryStatistics> summarizingDouble(ToDoubleFunction<? super T> mapper) {
1903         return new CollectorImpl<T, DoubleSummaryStatistics, DoubleSummaryStatistics>(
1904                 DoubleSummaryStatistics::new,
1905                 (r, t) -> r.accept(mapper.applyAsDouble(t)),
1906                 (l, r) -> { l.combine(r); return l; }, CH_ID);
1907     }
1908 
1909     /**
1910      * Returns a {@code Collector} that is a composite of two downstream collectors.
1911      * Every element passed to the resulting collector is processed by both downstream
1912      * collectors, then their results are merged using the specified merge function
1913      * into the final result.
1914      *
1915      * <p>The resulting collector functions do the following:
1916      *
1917      * <ul>
1918      * <li>supplier: creates a result container that contains result containers
1919      * obtained by calling each collector's supplier
1920      * <li>accumulator: calls each collector's accumulator with its result container
1921      * and the input element
1922      * <li>combiner: calls each collector's combiner with two result containers
1923      * <li>finisher: calls each collector's finisher with its result container,
1924      * then calls the supplied merger and returns its result.
1925      * </ul>
1926      *
1927      * <p>The resulting collector is {@link Collector.Characteristics#UNORDERED} if both downstream
1928      * collectors are unordered and {@link Collector.Characteristics#CONCURRENT} if both downstream
1929      * collectors are concurrent.
1930      *
1931      * @param <T>         the type of the input elements
1932      * @param <R1>        the result type of the first collector
1933      * @param <R2>        the result type of the second collector
1934      * @param <R>         the final result type
1935      * @param downstream1 the first downstream collector
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         Supplier<A1> c1Supplier = Objects.requireNonNull(downstream1.supplier(), "downstream1 supplier");
1957         Supplier<A2> c2Supplier = Objects.requireNonNull(downstream2.supplier(), "downstream2 supplier");
1958         IntFunction<A1> c1SizedSupplier =
1959                 Objects.requireNonNull(downstream1.sizedSupplier(), "downstream1 sizedSupplier");
1960         IntFunction<A2> c2SizedSupplier =
1961                 Objects.requireNonNull(downstream2.sizedSupplier(), "downstream2 sizedSupplier");
1962         BiConsumer<A1, ? super T> c1Accumulator =
1963                 Objects.requireNonNull(downstream1.accumulator(), "downstream1 accumulator");
1964         BiConsumer<A2, ? super T> c2Accumulator =
1965                 Objects.requireNonNull(downstream2.accumulator(), "downstream2 accumulator");
1966         BinaryOperator<A1> c1Combiner = Objects.requireNonNull(downstream1.combiner(), "downstream1 combiner");
1967         BinaryOperator<A2> c2Combiner = Objects.requireNonNull(downstream2.combiner(), "downstream2 combiner");
1968         Function<A1, R1> c1Finisher = Objects.requireNonNull(downstream1.finisher(), "downstream1 finisher");
1969         Function<A2, R2> c2Finisher = Objects.requireNonNull(downstream2.finisher(), "downstream2 finisher");
1970 
1971         Set<Collector.Characteristics> characteristics;
1972         Set<Collector.Characteristics> c1Characteristics = downstream1.characteristics();
1973         Set<Collector.Characteristics> c2Characteristics = downstream2.characteristics();
1974         if (CH_ID.containsAll(c1Characteristics) || CH_ID.containsAll(c2Characteristics)) {
1975             characteristics = CH_NOID;
1976         } else {
1977             EnumSet<Collector.Characteristics> c = EnumSet.noneOf(Collector.Characteristics.class);
1978             c.addAll(c1Characteristics);
1979             c.retainAll(c2Characteristics);
1980             c.remove(Collector.Characteristics.IDENTITY_FINISH);
1981             characteristics = Collections.unmodifiableSet(c);
1982         }
1983 
1984         class PairBox {
1985             A1 left;
1986             A2 right;
1987 
1988             PairBox(int initialSize) {
1989                 left = c1SizedSupplier.apply(initialSize);
1990                 right = c2SizedSupplier.apply(initialSize);
1991             }
1992 
1993             PairBox() {
1994                 left = c1Supplier.get();
1995                 right = c2Supplier.get();
1996             }
1997 
1998             void add(T t) {
1999                 c1Accumulator.accept(left, t);
2000                 c2Accumulator.accept(right, t);
2001             }
2002 
2003             PairBox combine(PairBox other) {
2004                 left = c1Combiner.apply(left, other.left);
2005                 right = c2Combiner.apply(right, other.right);
2006                 return this;
2007             }
2008 
2009             R get() {
2010                 R1 r1 = c1Finisher.apply(left);
2011                 R2 r2 = c2Finisher.apply(right);
2012                 return merger.apply(r1, r2);
2013             }
2014         }
2015 
2016         return new CollectorImpl<>(PairBox::new,
2017                                    PairBox::new,
2018                                    PairBox::add,
2019                                    PairBox::combine,
2020                                    PairBox::get,
2021                                    characteristics);
2022     }
2023 
2024     /**
2025      * Implementation class used by partitioningBy.
2026      */
2027     private static final class Partition<T>
2028             extends AbstractMap<Boolean, T>
2029             implements Map<Boolean, T> {
2030         final T forTrue;
2031         final T forFalse;
2032 
2033         Partition(T forTrue, T forFalse) {
2034             this.forTrue = forTrue;
2035             this.forFalse = forFalse;
2036         }
2037 
2038         @Override
2039         public Set<Map.Entry<Boolean, T>> entrySet() {
2040             return new AbstractSet<>() {
2041                 @Override
2042                 public Iterator<Map.Entry<Boolean, T>> iterator() {
2043                     Map.Entry<Boolean, T> falseEntry = new SimpleImmutableEntry<>(false, forFalse);
2044                     Map.Entry<Boolean, T> trueEntry = new SimpleImmutableEntry<>(true, forTrue);
2045                     return List.of(falseEntry, trueEntry).iterator();
2046                 }
2047 
2048                 @Override
2049                 public int size() {
2050                     return 2;
2051                 }
2052             };
2053         }
2054     }
2055 }