1 /*
   2  * Copyright (c) 2012, 2013, 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.Arrays;
  31 import java.util.Collection;
  32 import java.util.Collections;
  33 import java.util.Comparator;
  34 import java.util.DoubleSummaryStatistics;
  35 import java.util.EnumSet;
  36 import java.util.HashMap;
  37 import java.util.HashSet;
  38 import java.util.IntSummaryStatistics;
  39 import java.util.Iterator;
  40 import java.util.List;
  41 import java.util.LongSummaryStatistics;
  42 import java.util.Map;
  43 import java.util.Objects;
  44 import java.util.Optional;
  45 import java.util.Set;
  46 import java.util.StringJoiner;
  47 import java.util.concurrent.ConcurrentHashMap;
  48 import java.util.concurrent.ConcurrentMap;
  49 import java.util.function.BiConsumer;
  50 import java.util.function.BiFunction;
  51 import java.util.function.BinaryOperator;
  52 import java.util.function.Consumer;
  53 import java.util.function.Function;
  54 import java.util.function.Predicate;
  55 import java.util.function.Supplier;
  56 import java.util.function.ToDoubleFunction;
  57 import java.util.function.ToIntFunction;
  58 import java.util.function.ToLongFunction;
  59 
  60 /**
  61  * Implementations of {@link Collector} that implement various useful reduction
  62  * operations, such as accumulating elements into collections, summarizing
  63  * elements according to various criteria, etc.
  64  *
  65  * <p>The following are examples of using the predefined collectors to perform
  66  * common mutable reduction tasks:
  67  *
  68  * <pre>{@code
  69  *     // Accumulate names into a List
  70  *     List<String> list = people.stream().map(Person::getName).collect(Collectors.toList());
  71  *
  72  *     // Accumulate names into a TreeSet
  73  *     Set<String> set = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));
  74  *
  75  *     // Convert elements to strings and concatenate them, separated by commas
  76  *     String joined = things.stream()
  77  *                           .map(Object::toString)
  78  *                           .collect(Collectors.joining(", "));
  79  *
  80  *     // Compute sum of salaries of employee
  81  *     int total = employees.stream()
  82  *                          .collect(Collectors.summingInt(Employee::getSalary)));
  83  *
  84  *     // Group employees by department
  85  *     Map<Department, List<Employee>> byDept
  86  *         = employees.stream()
  87  *                    .collect(Collectors.groupingBy(Employee::getDepartment));
  88  *
  89  *     // Compute sum of salaries by department
  90  *     Map<Department, Integer> totalByDept
  91  *         = employees.stream()
  92  *                    .collect(Collectors.groupingBy(Employee::getDepartment,
  93  *                                                   Collectors.summingInt(Employee::getSalary)));
  94  *
  95  *     // Partition students into passing and failing
  96  *     Map<Boolean, List<Student>> passingFailing =
  97  *         students.stream()
  98  *                 .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
  99  *
 100  * }</pre>
 101  *
 102  * @since 1.8
 103  */
 104 public final class Collectors {
 105 
 106     static final Set<Collector.Characteristics> CH_CONCURRENT_ID
 107             = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.CONCURRENT,
 108                                                      Collector.Characteristics.UNORDERED,
 109                                                      Collector.Characteristics.IDENTITY_FINISH));
 110     static final Set<Collector.Characteristics> CH_CONCURRENT_NOID
 111             = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.CONCURRENT,
 112                                                      Collector.Characteristics.UNORDERED));
 113     static final Set<Collector.Characteristics> CH_ID
 114             = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH));
 115     static final Set<Collector.Characteristics> CH_UNORDERED_ID
 116             = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.UNORDERED,
 117                                                      Collector.Characteristics.IDENTITY_FINISH));
 118     static final Set<Collector.Characteristics> CH_NOID = Collections.emptySet();
 119 
 120     private Collectors() { }
 121 
 122     /**
 123      * Construct an {@code IllegalStateException} with appropriate message.
 124      *
 125      * @param k the duplicate key
 126      * @param u 1st value to be accumulated/merged
 127      * @param v 2nd value to be accumulated/merged
 128      */
 129     private static IllegalStateException duplicateKeyException(
 130             Object k, Object u, Object v) {
 131         return new IllegalStateException(String.format(
 132             "Duplicate key %s (attempted merging values %s and %s)",
 133             k, u, v));
 134     }
 135 
 136     /**
 137      * {@code BinaryOperator<Map>} that merges the contents of its right
 138      * argument into its left argument, throwing {@code IllegalStateException}
 139      * if duplicate keys are encountered.
 140      *
 141      * @param <K> type of the map keys
 142      * @param <V> type of the map values
 143      * @param <M> type of the map
 144      * {@link Map#merge(Object, Object, BiFunction) Map.merge()}
 145      * @return a merge function for two maps
 146      */
 147     private static <K, V, M extends Map<K,V>>
 148     BinaryOperator<M> uniqKeysMapMerger() {
 149         return (m1, m2) -> {
 150             for (Map.Entry<K,V> e : m2.entrySet()) {
 151                 K k = e.getKey();
 152                 V v = Objects.requireNonNull(e.getValue());
 153                 V u = m1.putIfAbsent(k, v);
 154                 if (u != null) throw duplicateKeyException(k, u, v);
 155             }
 156             return m1;
 157         };
 158     }
 159 
 160     /**
 161      * {@code BiConsumer<Map, T>} that accumulates (key, value) pairs
 162      * extracted from elements into the map, throwing {@code IllegalStateException}
 163      * if duplicate keys are encountered.
 164      *
 165      * @param keyMapper a function that maps an element into a key
 166      * @param valueMapper a function that maps an element into a value
 167      * @param <T> type of elements
 168      * @param <K> type of map keys
 169      * @param <V> type of map values
 170      * @return an accumulating consumer
 171      */
 172     private static <T, K, V>
 173     BiConsumer<Map<K, V>, T> uniqKeysMapAccumulator(Function<? super T, ? extends K> keyMapper,
 174                                                     Function<? super T, ? extends V> valueMapper) {
 175         return (map, element) -> {
 176             K k = keyMapper.apply(element);
 177             V v = Objects.requireNonNull(valueMapper.apply(element));
 178             V u = map.putIfAbsent(k, v);
 179             if (u != null) throw duplicateKeyException(k, u, v);
 180         };
 181     }
 182 
 183     @SuppressWarnings("unchecked")
 184     private static <I, R> Function<I, R> castingIdentity() {
 185         return i -> (R) i;
 186     }
 187 
 188     /**
 189      * Simple implementation class for {@code Collector}.
 190      *
 191      * @param <T> the type of elements to be collected
 192      * @param <R> the type of the result
 193      */
 194     static class CollectorImpl<T, A, R> implements Collector<T, A, R> {
 195         private final Supplier<A> supplier;
 196         private final BiConsumer<A, T> accumulator;
 197         private final BinaryOperator<A> combiner;
 198         private final Function<A, R> finisher;
 199         private final Set<Characteristics> characteristics;
 200 
 201         CollectorImpl(Supplier<A> supplier,
 202                       BiConsumer<A, T> accumulator,
 203                       BinaryOperator<A> combiner,
 204                       Function<A,R> finisher,
 205                       Set<Characteristics> characteristics) {
 206             this.supplier = supplier;
 207             this.accumulator = accumulator;
 208             this.combiner = combiner;
 209             this.finisher = finisher;
 210             this.characteristics = characteristics;
 211         }
 212 
 213         CollectorImpl(Supplier<A> supplier,
 214                       BiConsumer<A, T> accumulator,
 215                       BinaryOperator<A> combiner,
 216                       Set<Characteristics> characteristics) {
 217             this(supplier, accumulator, combiner, castingIdentity(), characteristics);
 218         }
 219 
 220         @Override
 221         public BiConsumer<A, T> accumulator() {
 222             return accumulator;
 223         }
 224 
 225         @Override
 226         public Supplier<A> supplier() {
 227             return supplier;
 228         }
 229 
 230         @Override
 231         public BinaryOperator<A> combiner() {
 232             return combiner;
 233         }
 234 
 235         @Override
 236         public Function<A, R> finisher() {
 237             return finisher;
 238         }
 239 
 240         @Override
 241         public Set<Characteristics> characteristics() {
 242             return characteristics;
 243         }
 244     }
 245 
 246     /**
 247      * Returns a {@code Collector} that accumulates the input elements into a
 248      * new {@code Collection}, in encounter order.  The {@code Collection} is
 249      * created by the provided factory.
 250      *
 251      * @param <T> the type of the input elements
 252      * @param <C> the type of the resulting {@code Collection}
 253      * @param collectionFactory a {@code Supplier} which returns a new, empty
 254      * {@code Collection} of the appropriate type
 255      * @return a {@code Collector} which collects all the input elements into a
 256      * {@code Collection}, in encounter order
 257      */
 258     public static <T, C extends Collection<T>>
 259     Collector<T, ?, C> toCollection(Supplier<C> collectionFactory) {
 260         return new CollectorImpl<>(collectionFactory, Collection<T>::add,
 261                                    (r1, r2) -> { r1.addAll(r2); return r1; },
 262                                    CH_ID);
 263     }
 264 
 265     /**
 266      * Returns a {@code Collector} that accumulates the input elements into a
 267      * new {@code List}. There are no guarantees on the type, mutability,
 268      * serializability, or thread-safety of the {@code List} returned; if more
 269      * control over the returned {@code List} is required, use {@link #toCollection(Supplier)}.
 270      *
 271      * @param <T> the type of the input elements
 272      * @return a {@code Collector} which collects all the input elements into a
 273      * {@code List}, in encounter order
 274      */
 275     public static <T>
 276     Collector<T, ?, List<T>> toList() {
 277         return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
 278                                    (left, right) -> { left.addAll(right); return left; },
 279                                    CH_ID);
 280     }
 281 
 282     /**
 283      * Returns a {@code Collector} that accumulates the input elements into a
 284      * new {@code Set}. There are no guarantees on the type, mutability,
 285      * serializability, or thread-safety of the {@code Set} returned; if more
 286      * control over the returned {@code Set} is required, use
 287      * {@link #toCollection(Supplier)}.
 288      *
 289      * <p>This is an {@link Collector.Characteristics#UNORDERED unordered}
 290      * Collector.
 291      *
 292      * @param <T> the type of the input elements
 293      * @return a {@code Collector} which collects all the input elements into a
 294      * {@code Set}
 295      */
 296     public static <T>
 297     Collector<T, ?, Set<T>> toSet() {
 298         return new CollectorImpl<>((Supplier<Set<T>>) HashSet::new, Set::add,
 299                                    (left, right) -> { left.addAll(right); return left; },
 300                                    CH_UNORDERED_ID);
 301     }
 302 
 303     /**
 304      * Returns a {@code Collector} that concatenates the input elements into a
 305      * {@code String}, in encounter order.
 306      *
 307      * @return a {@code Collector} that concatenates the input elements into a
 308      * {@code String}, in encounter order
 309      */
 310     public static Collector<CharSequence, ?, String> joining() {
 311         return new CollectorImpl<CharSequence, StringBuilder, String>(
 312                 StringBuilder::new, StringBuilder::append,
 313                 (r1, r2) -> { r1.append(r2); return r1; },
 314                 StringBuilder::toString, CH_NOID);
 315     }
 316 
 317     /**
 318      * Returns a {@code Collector} that concatenates the input elements,
 319      * separated by the specified delimiter, in encounter order.
 320      *
 321      * @param delimiter the delimiter to be used between each element
 322      * @return A {@code Collector} which concatenates CharSequence elements,
 323      * separated by the specified delimiter, in encounter order
 324      */
 325     public static Collector<CharSequence, ?, String> joining(CharSequence delimiter) {
 326         return joining(delimiter, "", "");
 327     }
 328 
 329     /**
 330      * Returns a {@code Collector} that concatenates the input elements,
 331      * separated by the specified delimiter, with the specified prefix and
 332      * suffix, in encounter order.
 333      *
 334      * @param delimiter the delimiter to be used between each element
 335      * @param  prefix the sequence of characters to be used at the beginning
 336      *                of the joined result
 337      * @param  suffix the sequence of characters to be used at the end
 338      *                of the joined result
 339      * @return A {@code Collector} which concatenates CharSequence elements,
 340      * separated by the specified delimiter, in encounter order
 341      */
 342     public static Collector<CharSequence, ?, String> joining(CharSequence delimiter,
 343                                                              CharSequence prefix,
 344                                                              CharSequence suffix) {
 345         return new CollectorImpl<>(
 346                 () -> new StringJoiner(delimiter, prefix, suffix),
 347                 StringJoiner::add, StringJoiner::merge,
 348                 StringJoiner::toString, CH_NOID);
 349     }
 350 
 351     /**
 352      * {@code BinaryOperator<Map>} that merges the contents of its right
 353      * argument into its left argument, using the provided merge function to
 354      * handle duplicate keys.
 355      *
 356      * @param <K> type of the map keys
 357      * @param <V> type of the map values
 358      * @param <M> type of the map
 359      * @param mergeFunction A merge function suitable for
 360      * {@link Map#merge(Object, Object, BiFunction) Map.merge()}
 361      * @return a merge function for two maps
 362      */
 363     private static <K, V, M extends Map<K,V>>
 364     BinaryOperator<M> mapMerger(BinaryOperator<V> mergeFunction) {
 365         return (m1, m2) -> {
 366             for (Map.Entry<K,V> e : m2.entrySet())
 367                 m1.merge(e.getKey(), e.getValue(), mergeFunction);
 368             return m1;
 369         };
 370     }
 371 
 372     /**
 373      * Adapts a {@code Collector} accepting elements of type {@code U} to one
 374      * accepting elements of type {@code T} by applying a mapping function to
 375      * each input element before accumulation.
 376      *
 377      * @apiNote
 378      * The {@code mapping()} collectors are most useful when used in a
 379      * multi-level reduction, such as downstream of a {@code groupingBy} or
 380      * {@code partitioningBy}.  For example, given a stream of
 381      * {@code Person}, to accumulate the set of last names in each city:
 382      * <pre>{@code
 383      *     Map<City, Set<String>> lastNamesByCity
 384      *         = people.stream().collect(groupingBy(Person::getCity,
 385      *                                              mapping(Person::getLastName, toSet())));
 386      * }</pre>
 387      *
 388      * @param <T> the type of the input elements
 389      * @param <U> type of elements accepted by downstream collector
 390      * @param <A> intermediate accumulation type of the downstream collector
 391      * @param <R> result type of collector
 392      * @param mapper a function to be applied to the input elements
 393      * @param downstream a collector which will accept mapped values
 394      * @return a collector which applies the mapping function to the input
 395      * elements and provides the mapped results to the downstream collector
 396      */
 397     public static <T, U, A, R>
 398     Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper,
 399                                Collector<? super U, A, R> downstream) {
 400         BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
 401         return new CollectorImpl<>(downstream.supplier(),
 402                                    (r, t) -> downstreamAccumulator.accept(r, mapper.apply(t)),
 403                                    downstream.combiner(), downstream.finisher(),
 404                                    downstream.characteristics());
 405     }
 406 
 407     /**
 408      * Adapts a {@code Collector} to perform an additional finishing
 409      * transformation.  For example, one could adapt the {@link #toList()}
 410      * collector to always produce an immutable list with:
 411      * <pre>{@code
 412      *     List<String> people
 413      *         = people.stream().collect(collectingAndThen(toList(), Collections::unmodifiableList));
 414      * }</pre>
 415      *
 416      * @param <T> the type of the input elements
 417      * @param <A> intermediate accumulation type of the downstream collector
 418      * @param <R> result type of the downstream collector
 419      * @param <RR> result type of the resulting collector
 420      * @param downstream a collector
 421      * @param finisher a function to be applied to the final result of the downstream collector
 422      * @return a collector which performs the action of the downstream collector,
 423      * followed by an additional finishing step
 424      */
 425     public static<T,A,R,RR> Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream,
 426                                                                 Function<R,RR> finisher) {
 427         Set<Collector.Characteristics> characteristics = downstream.characteristics();
 428         if (characteristics.contains(Collector.Characteristics.IDENTITY_FINISH)) {
 429             if (characteristics.size() == 1)
 430                 characteristics = Collectors.CH_NOID;
 431             else {
 432                 characteristics = EnumSet.copyOf(characteristics);
 433                 characteristics.remove(Collector.Characteristics.IDENTITY_FINISH);
 434                 characteristics = Collections.unmodifiableSet(characteristics);
 435             }
 436         }
 437         return new CollectorImpl<>(downstream.supplier(),
 438                                    downstream.accumulator(),
 439                                    downstream.combiner(),
 440                                    downstream.finisher().andThen(finisher),
 441                                    characteristics);
 442     }
 443 
 444     /**
 445      * Returns a {@code Collector} accepting elements of type {@code T} that
 446      * counts the number of input elements.  If no elements are present, the
 447      * result is 0.
 448      *
 449      * @implSpec
 450      * This produces a result equivalent to:
 451      * <pre>{@code
 452      *     reducing(0L, e -> 1L, Long::sum)
 453      * }</pre>
 454      *
 455      * @param <T> the type of the input elements
 456      * @return a {@code Collector} that counts the input elements
 457      */
 458     public static <T> Collector<T, ?, Long>
 459     counting() {
 460         return reducing(0L, e -> 1L, Long::sum);
 461     }
 462 
 463     /**
 464      * Returns a {@code Collector} that produces the minimal element according
 465      * to a given {@code Comparator}, described as an {@code Optional<T>}.
 466      *
 467      * @implSpec
 468      * This produces a result equivalent to:
 469      * <pre>{@code
 470      *     reducing(BinaryOperator.minBy(comparator))
 471      * }</pre>
 472      *
 473      * @param <T> the type of the input elements
 474      * @param comparator a {@code Comparator} for comparing elements
 475      * @return a {@code Collector} that produces the minimal value
 476      */
 477     public static <T> Collector<T, ?, Optional<T>>
 478     minBy(Comparator<? super T> comparator) {
 479         return reducing(BinaryOperator.minBy(comparator));
 480     }
 481 
 482     /**
 483      * Returns a {@code Collector} that produces the maximal element according
 484      * to a given {@code Comparator}, described as an {@code Optional<T>}.
 485      *
 486      * @implSpec
 487      * This produces a result equivalent to:
 488      * <pre>{@code
 489      *     reducing(BinaryOperator.maxBy(comparator))
 490      * }</pre>
 491      *
 492      * @param <T> the type of the input elements
 493      * @param comparator a {@code Comparator} for comparing elements
 494      * @return a {@code Collector} that produces the maximal value
 495      */
 496     public static <T> Collector<T, ?, Optional<T>>
 497     maxBy(Comparator<? super T> comparator) {
 498         return reducing(BinaryOperator.maxBy(comparator));
 499     }
 500 
 501     /**
 502      * Returns a {@code Collector} that produces the sum of a integer-valued
 503      * function applied to the input elements.  If no elements are present,
 504      * the result is 0.
 505      *
 506      * @param <T> the type of the input elements
 507      * @param mapper a function extracting the property to be summed
 508      * @return a {@code Collector} that produces the sum of a derived property
 509      */
 510     public static <T> Collector<T, ?, Integer>
 511     summingInt(ToIntFunction<? super T> mapper) {
 512         return new CollectorImpl<>(
 513                 () -> new int[1],
 514                 (a, t) -> { a[0] += mapper.applyAsInt(t); },
 515                 (a, b) -> { a[0] += b[0]; return a; },
 516                 a -> a[0], CH_NOID);
 517     }
 518 
 519     /**
 520      * Returns a {@code Collector} that produces the sum of a long-valued
 521      * function applied to the input elements.  If no elements are present,
 522      * the result is 0.
 523      *
 524      * @param <T> the type of the input elements
 525      * @param mapper a function extracting the property to be summed
 526      * @return a {@code Collector} that produces the sum of a derived property
 527      */
 528     public static <T> Collector<T, ?, Long>
 529     summingLong(ToLongFunction<? super T> mapper) {
 530         return new CollectorImpl<>(
 531                 () -> new long[1],
 532                 (a, t) -> { a[0] += mapper.applyAsLong(t); },
 533                 (a, b) -> { a[0] += b[0]; return a; },
 534                 a -> a[0], CH_NOID);
 535     }
 536 
 537     /**
 538      * Returns a {@code Collector} that produces the sum of a double-valued
 539      * function applied to the input elements.  If no elements are present,
 540      * the result is 0.
 541      *
 542      * <p>The sum returned can vary depending upon the order in which
 543      * values are recorded, due to accumulated rounding error in
 544      * addition of values of differing magnitudes. Values sorted by increasing
 545      * absolute magnitude tend to yield more accurate results.  If any recorded
 546      * value is a {@code NaN} or the sum is at any point a {@code NaN} then the
 547      * sum will be {@code NaN}.
 548      *
 549      * @param <T> the type of the input elements
 550      * @param mapper a function extracting the property to be summed
 551      * @return a {@code Collector} that produces the sum of a derived property
 552      */
 553     public static <T> Collector<T, ?, Double>
 554     summingDouble(ToDoubleFunction<? super T> mapper) {
 555         /*
 556          * In the arrays allocated for the collect operation, index 0
 557          * holds the high-order bits of the running sum, index 1 holds
 558          * the low-order bits of the sum computed via compensated
 559          * summation, and index 2 holds the simple sum used to compute
 560          * the proper result if the stream contains infinite values of
 561          * the same sign.
 562          */
 563         return new CollectorImpl<>(
 564                 () -> new double[3],
 565                 (a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t));
 566                             a[2] += mapper.applyAsDouble(t);},
 567                 (a, b) -> { sumWithCompensation(a, b[0]);
 568                             a[2] += b[2];
 569                             return sumWithCompensation(a, b[1]); },
 570                 a -> computeFinalSum(a),
 571                 CH_NOID);
 572     }
 573 
 574     /**
 575      * Incorporate a new double value using Kahan summation /
 576      * compensation summation.
 577      *
 578      * High-order bits of the sum are in intermediateSum[0], low-order
 579      * bits of the sum are in intermediateSum[1], any additional
 580      * elements are application-specific.
 581      *
 582      * @param intermediateSum the high-order and low-order words of the intermediate sum
 583      * @param value the name value to be included in the running sum
 584      */
 585     static double[] sumWithCompensation(double[] intermediateSum, double value) {
 586         double tmp = value - intermediateSum[1];
 587         double sum = intermediateSum[0];
 588         double velvel = sum + tmp; // Little wolf of rounding error
 589         intermediateSum[1] = (velvel - sum) - tmp;
 590         intermediateSum[0] = velvel;
 591         return intermediateSum;
 592     }
 593 
 594     /**
 595      * If the compensated sum is spuriously NaN from accumulating one
 596      * or more same-signed infinite values, return the
 597      * correctly-signed infinity stored in the simple sum.
 598      */
 599     static double computeFinalSum(double[] summands) {
 600         // Better error bounds to add both terms as the final sum
 601         double tmp = summands[0] + summands[1];
 602         double simpleSum = summands[summands.length - 1];
 603         if (Double.isNaN(tmp) && Double.isInfinite(simpleSum))
 604             return simpleSum;
 605         else
 606             return tmp;
 607     }
 608 
 609     /**
 610      * Returns a {@code Collector} that produces the arithmetic mean of an integer-valued
 611      * function applied to the input elements.  If no elements are present,
 612      * the result is 0.
 613      *
 614      * @param <T> the type of the input elements
 615      * @param mapper a function extracting the property to be summed
 616      * @return a {@code Collector} that produces the sum of a derived property
 617      */
 618     public static <T> Collector<T, ?, Double>
 619     averagingInt(ToIntFunction<? super T> mapper) {
 620         return new CollectorImpl<>(
 621                 () -> new long[2],
 622                 (a, t) -> { a[0] += mapper.applyAsInt(t); a[1]++; },
 623                 (a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; },
 624                 a -> (a[1] == 0) ? 0.0d : (double) a[0] / a[1], CH_NOID);
 625     }
 626 
 627     /**
 628      * Returns a {@code Collector} that produces the arithmetic mean of a long-valued
 629      * function applied to the input elements.  If no elements are present,
 630      * the result is 0.
 631      *
 632      * @param <T> the type of the input elements
 633      * @param mapper a function extracting the property to be summed
 634      * @return a {@code Collector} that produces the sum of a derived property
 635      */
 636     public static <T> Collector<T, ?, Double>
 637     averagingLong(ToLongFunction<? super T> mapper) {
 638         return new CollectorImpl<>(
 639                 () -> new long[2],
 640                 (a, t) -> { a[0] += mapper.applyAsLong(t); a[1]++; },
 641                 (a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; },
 642                 a -> (a[1] == 0) ? 0.0d : (double) a[0] / a[1], CH_NOID);
 643     }
 644 
 645     /**
 646      * Returns a {@code Collector} that produces the arithmetic mean of a double-valued
 647      * function applied to the input elements.  If no elements are present,
 648      * the result is 0.
 649      *
 650      * <p>The average returned can vary depending upon the order in which
 651      * values are recorded, due to accumulated rounding error in
 652      * addition of values of differing magnitudes. Values sorted by increasing
 653      * absolute magnitude tend to yield more accurate results.  If any recorded
 654      * value is a {@code NaN} or the sum is at any point a {@code NaN} then the
 655      * average will be {@code NaN}.
 656      *
 657      * @implNote The {@code double} format can represent all
 658      * consecutive integers in the range -2<sup>53</sup> to
 659      * 2<sup>53</sup>. If the pipeline has more than 2<sup>53</sup>
 660      * values, the divisor in the average computation will saturate at
 661      * 2<sup>53</sup>, leading to additional numerical errors.
 662      *
 663      * @param <T> the type of the input elements
 664      * @param mapper a function extracting the property to be summed
 665      * @return a {@code Collector} that produces the sum of a derived property
 666      */
 667     public static <T> Collector<T, ?, Double>
 668     averagingDouble(ToDoubleFunction<? super T> mapper) {
 669         /*
 670          * In the arrays allocated for the collect operation, index 0
 671          * holds the high-order bits of the running sum, index 1 holds
 672          * the low-order bits of the sum computed via compensated
 673          * summation, and index 2 holds the number of values seen.
 674          */
 675         return new CollectorImpl<>(
 676                 () -> new double[4],
 677                 (a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t)); a[2]++; a[3]+= mapper.applyAsDouble(t);},
 678                 (a, b) -> { sumWithCompensation(a, b[0]); sumWithCompensation(a, b[1]); a[2] += b[2]; a[3] += b[3]; return a; },
 679                 a -> (a[2] == 0) ? 0.0d : (computeFinalSum(a) / a[2]),
 680                 CH_NOID);
 681     }
 682 
 683     /**
 684      * Returns a {@code Collector} which performs a reduction of its
 685      * input elements under a specified {@code BinaryOperator} using the
 686      * provided identity.
 687      *
 688      * @apiNote
 689      * The {@code reducing()} collectors are most useful when used in a
 690      * multi-level reduction, downstream of {@code groupingBy} or
 691      * {@code partitioningBy}.  To perform a simple reduction on a stream,
 692      * use {@link Stream#reduce(Object, BinaryOperator)}} instead.
 693      *
 694      * @param <T> element type for the input and output of the reduction
 695      * @param identity the identity value for the reduction (also, the value
 696      *                 that is returned when there are no input elements)
 697      * @param op a {@code BinaryOperator<T>} used to reduce the input elements
 698      * @return a {@code Collector} which implements the reduction operation
 699      *
 700      * @see #reducing(BinaryOperator)
 701      * @see #reducing(Object, Function, BinaryOperator)
 702      */
 703     public static <T> Collector<T, ?, T>
 704     reducing(T identity, BinaryOperator<T> op) {
 705         return new CollectorImpl<>(
 706                 boxSupplier(identity),
 707                 (a, t) -> { a[0] = op.apply(a[0], t); },
 708                 (a, b) -> { a[0] = op.apply(a[0], b[0]); return a; },
 709                 a -> a[0],
 710                 CH_NOID);
 711     }
 712 
 713     @SuppressWarnings("unchecked")
 714     private static <T> Supplier<T[]> boxSupplier(T identity) {
 715         return () -> (T[]) new Object[] { identity };
 716     }
 717 
 718     /**
 719      * Returns a {@code Collector} which performs a reduction of its
 720      * input elements under a specified {@code BinaryOperator}.  The result
 721      * is described as an {@code Optional<T>}.
 722      *
 723      * @apiNote
 724      * The {@code reducing()} collectors are most useful when used in a
 725      * multi-level reduction, downstream of {@code groupingBy} or
 726      * {@code partitioningBy}.  To perform a simple reduction on a stream,
 727      * use {@link Stream#reduce(BinaryOperator)} instead.
 728      *
 729      * <p>For example, given a stream of {@code Person}, to calculate tallest
 730      * person in each city:
 731      * <pre>{@code
 732      *     Comparator<Person> byHeight = Comparator.comparing(Person::getHeight);
 733      *     Map<City, Person> tallestByCity
 734      *         = people.stream().collect(groupingBy(Person::getCity, reducing(BinaryOperator.maxBy(byHeight))));
 735      * }</pre>
 736      *
 737      * @param <T> element type for the input and output of the reduction
 738      * @param op a {@code BinaryOperator<T>} used to reduce the input elements
 739      * @return a {@code Collector} which implements the reduction operation
 740      *
 741      * @see #reducing(Object, BinaryOperator)
 742      * @see #reducing(Object, Function, BinaryOperator)
 743      */
 744     public static <T> Collector<T, ?, Optional<T>>
 745     reducing(BinaryOperator<T> op) {
 746         class OptionalBox implements Consumer<T> {
 747             T value = null;
 748             boolean present = false;
 749 
 750             @Override
 751             public void accept(T t) {
 752                 if (present) {
 753                     value = op.apply(value, t);
 754                 }
 755                 else {
 756                     value = t;
 757                     present = true;
 758                 }
 759             }
 760         }
 761 
 762         return new CollectorImpl<T, OptionalBox, Optional<T>>(
 763                 OptionalBox::new, OptionalBox::accept,
 764                 (a, b) -> { if (b.present) a.accept(b.value); return a; },
 765                 a -> Optional.ofNullable(a.value), CH_NOID);
 766     }
 767 
 768     /**
 769      * Returns a {@code Collector} which performs a reduction of its
 770      * input elements under a specified mapping function and
 771      * {@code BinaryOperator}. This is a generalization of
 772      * {@link #reducing(Object, BinaryOperator)} which allows a transformation
 773      * of the elements before reduction.
 774      *
 775      * @apiNote
 776      * The {@code reducing()} collectors are most useful when used in a
 777      * multi-level reduction, downstream of {@code groupingBy} or
 778      * {@code partitioningBy}.  To perform a simple map-reduce on a stream,
 779      * use {@link Stream#map(Function)} and {@link Stream#reduce(Object, BinaryOperator)}
 780      * instead.
 781      *
 782      * <p>For example, given a stream of {@code Person}, to calculate the longest
 783      * last name of residents in each city:
 784      * <pre>{@code
 785      *     Comparator<String> byLength = Comparator.comparing(String::length);
 786      *     Map<City, String> longestLastNameByCity
 787      *         = people.stream().collect(groupingBy(Person::getCity,
 788      *                                              reducing(Person::getLastName, BinaryOperator.maxBy(byLength))));
 789      * }</pre>
 790      *
 791      * @param <T> the type of the input elements
 792      * @param <U> the type of the mapped values
 793      * @param identity the identity value for the reduction (also, the value
 794      *                 that is returned when there are no input elements)
 795      * @param mapper a mapping function to apply to each input value
 796      * @param op a {@code BinaryOperator<U>} used to reduce the mapped values
 797      * @return a {@code Collector} implementing the map-reduce operation
 798      *
 799      * @see #reducing(Object, BinaryOperator)
 800      * @see #reducing(BinaryOperator)
 801      */
 802     public static <T, U>
 803     Collector<T, ?, U> reducing(U identity,
 804                                 Function<? super T, ? extends U> mapper,
 805                                 BinaryOperator<U> op) {
 806         return new CollectorImpl<>(
 807                 boxSupplier(identity),
 808                 (a, t) -> { a[0] = op.apply(a[0], mapper.apply(t)); },
 809                 (a, b) -> { a[0] = op.apply(a[0], b[0]); return a; },
 810                 a -> a[0], CH_NOID);
 811     }
 812 
 813     /**
 814      * Returns a {@code Collector} implementing a "group by" operation on
 815      * input elements of type {@code T}, grouping elements according to a
 816      * classification function, and returning the results in a {@code Map}.
 817      *
 818      * <p>The classification function maps elements to some key type {@code K}.
 819      * The collector produces a {@code Map<K, List<T>>} whose keys are the
 820      * values resulting from applying the classification function to the input
 821      * elements, and whose corresponding values are {@code List}s containing the
 822      * input elements which map to the associated key under the classification
 823      * function.
 824      *
 825      * <p>There are no guarantees on the type, mutability, serializability, or
 826      * thread-safety of the {@code Map} or {@code List} objects returned.
 827      * @implSpec
 828      * This produces a result similar to:
 829      * <pre>{@code
 830      *     groupingBy(classifier, toList());
 831      * }</pre>
 832      *
 833      * @implNote
 834      * The returned {@code Collector} is not concurrent.  For parallel stream
 835      * pipelines, the {@code combiner} function operates by merging the keys
 836      * from one map into another, which can be an expensive operation.  If
 837      * preservation of the order in which elements appear in the resulting {@code Map}
 838      * collector is not required, using {@link #groupingByConcurrent(Function)}
 839      * may offer better parallel performance.
 840      *
 841      * @param <T> the type of the input elements
 842      * @param <K> the type of the keys
 843      * @param classifier the classifier function mapping input elements to keys
 844      * @return a {@code Collector} implementing the group-by operation
 845      *
 846      * @see #groupingBy(Function, Collector)
 847      * @see #groupingBy(Function, Supplier, Collector)
 848      * @see #groupingByConcurrent(Function)
 849      */
 850     public static <T, K> Collector<T, ?, Map<K, List<T>>>
 851     groupingBy(Function<? super T, ? extends K> classifier) {
 852         return groupingBy(classifier, toList());
 853     }
 854 
 855     /**
 856      * Returns a {@code Collector} implementing a cascaded "group by" operation
 857      * on input elements of type {@code T}, grouping elements according to a
 858      * classification function, and then performing a reduction operation on
 859      * the values associated with a given key using the specified downstream
 860      * {@code Collector}.
 861      *
 862      * <p>The classification function maps elements to some key type {@code K}.
 863      * The downstream collector operates on elements of type {@code T} and
 864      * produces a result of type {@code D}. The resulting collector produces a
 865      * {@code Map<K, D>}.
 866      *
 867      * <p>There are no guarantees on the type, mutability,
 868      * serializability, or thread-safety of the {@code Map} returned.
 869      *
 870      * <p>For example, to compute the set of last names of people in each city:
 871      * <pre>{@code
 872      *     Map<City, Set<String>> namesByCity
 873      *         = people.stream().collect(groupingBy(Person::getCity,
 874      *                                              mapping(Person::getLastName, toSet())));
 875      * }</pre>
 876      *
 877      * @implNote
 878      * The returned {@code Collector} is not concurrent.  For parallel stream
 879      * pipelines, the {@code combiner} function operates by merging the keys
 880      * from one map into another, which can be an expensive operation.  If
 881      * preservation of the order in which elements are presented to the downstream
 882      * collector is not required, using {@link #groupingByConcurrent(Function, Collector)}
 883      * may offer better parallel performance.
 884      *
 885      * @param <T> the type of the input elements
 886      * @param <K> the type of the keys
 887      * @param <A> the intermediate accumulation type of the downstream collector
 888      * @param <D> the result type of the downstream reduction
 889      * @param classifier a classifier function mapping input elements to keys
 890      * @param downstream a {@code Collector} implementing the downstream reduction
 891      * @return a {@code Collector} implementing the cascaded group-by operation
 892      * @see #groupingBy(Function)
 893      *
 894      * @see #groupingBy(Function, Supplier, Collector)
 895      * @see #groupingByConcurrent(Function, Collector)
 896      */
 897     public static <T, K, A, D>
 898     Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,
 899                                           Collector<? super T, A, D> downstream) {
 900         return groupingBy(classifier, HashMap::new, downstream);
 901     }
 902 
 903     /**
 904      * Returns a {@code Collector} implementing a cascaded "group by" operation
 905      * on input elements of type {@code T}, grouping elements according to a
 906      * classification function, and then performing a reduction operation on
 907      * the values associated with a given key using the specified downstream
 908      * {@code Collector}.  The {@code Map} produced by the Collector is created
 909      * with the supplied factory function.
 910      *
 911      * <p>The classification function maps elements to some key type {@code K}.
 912      * The downstream collector operates on elements of type {@code T} and
 913      * produces a result of type {@code D}. The resulting collector produces a
 914      * {@code Map<K, D>}.
 915      *
 916      * <p>For example, to compute the set of last names of people in each city,
 917      * where the city names are sorted:
 918      * <pre>{@code
 919      *     Map<City, Set<String>> namesByCity
 920      *         = people.stream().collect(groupingBy(Person::getCity, TreeMap::new,
 921      *                                              mapping(Person::getLastName, toSet())));
 922      * }</pre>
 923      *
 924      * @implNote
 925      * The returned {@code Collector} is not concurrent.  For parallel stream
 926      * pipelines, the {@code combiner} function operates by merging the keys
 927      * from one map into another, which can be an expensive operation.  If
 928      * preservation of the order in which elements are presented to the downstream
 929      * collector is not required, using {@link #groupingByConcurrent(Function, Supplier, Collector)}
 930      * may offer better parallel performance.
 931      *
 932      * @param <T> the type of the input elements
 933      * @param <K> the type of the keys
 934      * @param <A> the intermediate accumulation type of the downstream collector
 935      * @param <D> the result type of the downstream reduction
 936      * @param <M> the type of the resulting {@code Map}
 937      * @param classifier a classifier function mapping input elements to keys
 938      * @param downstream a {@code Collector} implementing the downstream reduction
 939      * @param mapFactory a function which, when called, produces a new empty
 940      *                   {@code Map} of the desired type
 941      * @return a {@code Collector} implementing the cascaded group-by operation
 942      *
 943      * @see #groupingBy(Function, Collector)
 944      * @see #groupingBy(Function)
 945      * @see #groupingByConcurrent(Function, Supplier, Collector)
 946      */
 947     public static <T, K, D, A, M extends Map<K, D>>
 948     Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier,
 949                                   Supplier<M> mapFactory,
 950                                   Collector<? super T, A, D> downstream) {
 951         Supplier<A> downstreamSupplier = downstream.supplier();
 952         BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
 953         BiConsumer<Map<K, A>, T> accumulator = (m, t) -> {
 954             K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
 955             A container = m.computeIfAbsent(key, k -> downstreamSupplier.get());
 956             downstreamAccumulator.accept(container, t);
 957         };
 958         BinaryOperator<Map<K, A>> merger = Collectors.<K, A, Map<K, A>>mapMerger(downstream.combiner());
 959         @SuppressWarnings("unchecked")
 960         Supplier<Map<K, A>> mangledFactory = (Supplier<Map<K, A>>) mapFactory;
 961 
 962         if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
 963             return new CollectorImpl<>(mangledFactory, accumulator, merger, CH_ID);
 964         }
 965         else {
 966             @SuppressWarnings("unchecked")
 967             Function<A, A> downstreamFinisher = (Function<A, A>) downstream.finisher();
 968             Function<Map<K, A>, M> finisher = intermediate -> {
 969                 intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v));
 970                 @SuppressWarnings("unchecked")
 971                 M castResult = (M) intermediate;
 972                 return castResult;
 973             };
 974             return new CollectorImpl<>(mangledFactory, accumulator, merger, finisher, CH_NOID);
 975         }
 976     }
 977 
 978     /**
 979      * Returns a concurrent {@code Collector} implementing a "group by"
 980      * operation on input elements of type {@code T}, grouping elements
 981      * according to a classification function.
 982      *
 983      * <p>This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
 984      * {@link Collector.Characteristics#UNORDERED unordered} Collector.
 985      *
 986      * <p>The classification function maps elements to some key type {@code K}.
 987      * The collector produces a {@code ConcurrentMap<K, List<T>>} whose keys are the
 988      * values resulting from applying the classification function to the input
 989      * elements, and whose corresponding values are {@code List}s containing the
 990      * input elements which map to the associated key under the classification
 991      * function.
 992      *
 993      * <p>There are no guarantees on the type, mutability, or serializability
 994      * of the {@code Map} or {@code List} objects returned, or of the
 995      * thread-safety of the {@code List} objects returned.
 996      * @implSpec
 997      * This produces a result similar to:
 998      * <pre>{@code
 999      *     groupingByConcurrent(classifier, toList());
1000      * }</pre>
1001      *
1002      * @param <T> the type of the input elements
1003      * @param <K> the type of the keys
1004      * @param classifier a classifier function mapping input elements to keys
1005      * @return a concurrent, unordered {@code Collector} implementing the group-by operation
1006      *
1007      * @see #groupingBy(Function)
1008      * @see #groupingByConcurrent(Function, Collector)
1009      * @see #groupingByConcurrent(Function, Supplier, Collector)
1010      */
1011     public static <T, K>
1012     Collector<T, ?, ConcurrentMap<K, List<T>>>
1013     groupingByConcurrent(Function<? super T, ? extends K> classifier) {
1014         return groupingByConcurrent(classifier, ConcurrentHashMap::new, toList());
1015     }
1016 
1017     /**
1018      * Returns a concurrent {@code Collector} implementing a cascaded "group by"
1019      * operation on input elements of type {@code T}, grouping elements
1020      * according to a classification function, and then performing a reduction
1021      * operation on the values associated with a given key using the specified
1022      * downstream {@code Collector}.
1023      *
1024      * <p>This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
1025      * {@link Collector.Characteristics#UNORDERED unordered} Collector.
1026      *
1027      * <p>The classification function maps elements to some key type {@code K}.
1028      * The downstream collector operates on elements of type {@code T} and
1029      * produces a result of type {@code D}. The resulting collector produces a
1030      * {@code Map<K, D>}.
1031      *
1032      * <p>For example, to compute the set of last names of people in each city,
1033      * where the city names are sorted:
1034      * <pre>{@code
1035      *     ConcurrentMap<City, Set<String>> namesByCity
1036      *         = people.stream().collect(groupingByConcurrent(Person::getCity,
1037      *                                                        mapping(Person::getLastName, toSet())));
1038      * }</pre>
1039      *
1040      * @param <T> the type of the input elements
1041      * @param <K> the type of the keys
1042      * @param <A> the intermediate accumulation type of the downstream collector
1043      * @param <D> the result type of the downstream reduction
1044      * @param classifier a classifier function mapping input elements to keys
1045      * @param downstream a {@code Collector} implementing the downstream reduction
1046      * @return a concurrent, unordered {@code Collector} implementing the cascaded group-by operation
1047      *
1048      * @see #groupingBy(Function, Collector)
1049      * @see #groupingByConcurrent(Function)
1050      * @see #groupingByConcurrent(Function, Supplier, Collector)
1051      */
1052     public static <T, K, A, D>
1053     Collector<T, ?, ConcurrentMap<K, D>> groupingByConcurrent(Function<? super T, ? extends K> classifier,
1054                                                               Collector<? super T, A, D> downstream) {
1055         return groupingByConcurrent(classifier, ConcurrentHashMap::new, downstream);
1056     }
1057 
1058     /**
1059      * Returns a concurrent {@code Collector} implementing a cascaded "group by"
1060      * operation on input elements of type {@code T}, grouping elements
1061      * according to a classification function, and then performing a reduction
1062      * operation on the values associated with a given key using the specified
1063      * downstream {@code Collector}.  The {@code ConcurrentMap} produced by the
1064      * Collector is created with the supplied factory function.
1065      *
1066      * <p>This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
1067      * {@link Collector.Characteristics#UNORDERED unordered} Collector.
1068      *
1069      * <p>The classification function maps elements to some key type {@code K}.
1070      * The downstream collector operates on elements of type {@code T} and
1071      * produces a result of type {@code D}. The resulting collector produces a
1072      * {@code Map<K, D>}.
1073      *
1074      * <p>For example, to compute the set of last names of people in each city,
1075      * where the city names are sorted:
1076      * <pre>{@code
1077      *     ConcurrentMap<City, Set<String>> namesByCity
1078      *         = people.stream().collect(groupingBy(Person::getCity, ConcurrentSkipListMap::new,
1079      *                                              mapping(Person::getLastName, toSet())));
1080      * }</pre>
1081      *
1082      *
1083      * @param <T> the type of the input elements
1084      * @param <K> the type of the keys
1085      * @param <A> the intermediate accumulation type of the downstream collector
1086      * @param <D> the result type of the downstream reduction
1087      * @param <M> the type of the resulting {@code ConcurrentMap}
1088      * @param classifier a classifier function mapping input elements to keys
1089      * @param downstream a {@code Collector} implementing the downstream reduction
1090      * @param mapFactory a function which, when called, produces a new empty
1091      *                   {@code ConcurrentMap} of the desired type
1092      * @return a concurrent, unordered {@code Collector} implementing the cascaded group-by operation
1093      *
1094      * @see #groupingByConcurrent(Function)
1095      * @see #groupingByConcurrent(Function, Collector)
1096      * @see #groupingBy(Function, Supplier, Collector)
1097      */
1098     public static <T, K, A, D, M extends ConcurrentMap<K, D>>
1099     Collector<T, ?, M> groupingByConcurrent(Function<? super T, ? extends K> classifier,
1100                                             Supplier<M> mapFactory,
1101                                             Collector<? super T, A, D> downstream) {
1102         Supplier<A> downstreamSupplier = downstream.supplier();
1103         BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
1104         BinaryOperator<ConcurrentMap<K, A>> merger = Collectors.<K, A, ConcurrentMap<K, A>>mapMerger(downstream.combiner());
1105         @SuppressWarnings("unchecked")
1106         Supplier<ConcurrentMap<K, A>> mangledFactory = (Supplier<ConcurrentMap<K, A>>) mapFactory;
1107         BiConsumer<ConcurrentMap<K, A>, T> accumulator;
1108         if (downstream.characteristics().contains(Collector.Characteristics.CONCURRENT)) {
1109             accumulator = (m, t) -> {
1110                 K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
1111                 A resultContainer = m.computeIfAbsent(key, k -> downstreamSupplier.get());
1112                 downstreamAccumulator.accept(resultContainer, t);
1113             };
1114         }
1115         else {
1116             accumulator = (m, t) -> {
1117                 K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
1118                 A resultContainer = m.computeIfAbsent(key, k -> downstreamSupplier.get());
1119                 synchronized (resultContainer) {
1120                     downstreamAccumulator.accept(resultContainer, t);
1121                 }
1122             };
1123         }
1124 
1125         if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
1126             return new CollectorImpl<>(mangledFactory, accumulator, merger, CH_CONCURRENT_ID);
1127         }
1128         else {
1129             @SuppressWarnings("unchecked")
1130             Function<A, A> downstreamFinisher = (Function<A, A>) downstream.finisher();
1131             Function<ConcurrentMap<K, A>, M> finisher = intermediate -> {
1132                 intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v));
1133                 @SuppressWarnings("unchecked")
1134                 M castResult = (M) intermediate;
1135                 return castResult;
1136             };
1137             return new CollectorImpl<>(mangledFactory, accumulator, merger, finisher, CH_CONCURRENT_NOID);
1138         }
1139     }
1140 
1141     /**
1142      * Returns a {@code Collector} which partitions the input elements according
1143      * to a {@code Predicate}, and organizes them into a
1144      * {@code Map<Boolean, List<T>>}.
1145      *
1146      * There are no guarantees on the type, mutability,
1147      * serializability, or thread-safety of the {@code Map} returned.
1148      *
1149      * @param <T> the type of the input elements
1150      * @param predicate a predicate used for classifying input elements
1151      * @return a {@code Collector} implementing the partitioning operation
1152      *
1153      * @see #partitioningBy(Predicate, Collector)
1154      */
1155     public static <T>
1156     Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate) {
1157         return partitioningBy(predicate, toList());
1158     }
1159 
1160     /**
1161      * Returns a {@code Collector} which partitions the input elements according
1162      * to a {@code Predicate}, reduces the values in each partition according to
1163      * another {@code Collector}, and organizes them into a
1164      * {@code Map<Boolean, D>} whose values are the result of the downstream
1165      * reduction.
1166      *
1167      * <p>There are no guarantees on the type, mutability,
1168      * serializability, or thread-safety of the {@code Map} returned.
1169      *
1170      * @param <T> the type of the input elements
1171      * @param <A> the intermediate accumulation type of the downstream collector
1172      * @param <D> the result type of the downstream reduction
1173      * @param predicate a predicate used for classifying input elements
1174      * @param downstream a {@code Collector} implementing the downstream
1175      *                   reduction
1176      * @return a {@code Collector} implementing the cascaded partitioning
1177      *         operation
1178      *
1179      * @see #partitioningBy(Predicate)
1180      */
1181     public static <T, D, A>
1182     Collector<T, ?, Map<Boolean, D>> partitioningBy(Predicate<? super T> predicate,
1183                                                     Collector<? super T, A, D> downstream) {
1184         BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
1185         BiConsumer<Partition<A>, T> accumulator = (result, t) ->
1186                 downstreamAccumulator.accept(predicate.test(t) ? result.forTrue : result.forFalse, t);
1187         BinaryOperator<A> op = downstream.combiner();
1188         BinaryOperator<Partition<A>> merger = (left, right) ->
1189                 new Partition<>(op.apply(left.forTrue, right.forTrue),
1190                                 op.apply(left.forFalse, right.forFalse));
1191         Supplier<Partition<A>> supplier = () ->
1192                 new Partition<>(downstream.supplier().get(),
1193                                 downstream.supplier().get());
1194         if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
1195             return new CollectorImpl<>(supplier, accumulator, merger, CH_ID);
1196         }
1197         else {
1198             Function<Partition<A>, Map<Boolean, D>> finisher = par ->
1199                     new Partition<>(downstream.finisher().apply(par.forTrue),
1200                                     downstream.finisher().apply(par.forFalse));
1201             return new CollectorImpl<>(supplier, accumulator, merger, finisher, CH_NOID);
1202         }
1203     }
1204 
1205     /**
1206      * Returns a {@code Collector} that accumulates elements into a
1207      * {@code Map} whose keys and values are the result of applying the provided
1208      * mapping functions to the input elements.
1209      *
1210      * <p>If the mapped keys contains duplicates (according to
1211      * {@link Object#equals(Object)}), an {@code IllegalStateException} is
1212      * thrown when the collection operation is performed.  If the mapped keys
1213      * may have duplicates, use {@link #toMap(Function, Function, BinaryOperator)}
1214      * instead.
1215      *
1216      * @apiNote
1217      * It is common for either the key or the value to be the input elements.
1218      * In this case, the utility method
1219      * {@link java.util.function.Function#identity()} may be helpful.
1220      * For example, the following produces a {@code Map} mapping
1221      * students to their grade point average:
1222      * <pre>{@code
1223      *     Map<Student, Double> studentToGPA
1224      *         students.stream().collect(toMap(Functions.identity(),
1225      *                                         student -> computeGPA(student)));
1226      * }</pre>
1227      * And the following produces a {@code Map} mapping a unique identifier to
1228      * students:
1229      * <pre>{@code
1230      *     Map<String, Student> studentIdToStudent
1231      *         students.stream().collect(toMap(Student::getId,
1232      *                                         Functions.identity());
1233      * }</pre>
1234      *
1235      * @implNote
1236      * The returned {@code Collector} is not concurrent.  For parallel stream
1237      * pipelines, the {@code combiner} function operates by merging the keys
1238      * from one map into another, which can be an expensive operation.  If it is
1239      * not required that results are inserted into the {@code Map} in encounter
1240      * order, using {@link #toConcurrentMap(Function, Function)}
1241      * may offer better parallel performance.
1242      *
1243      * @param <T> the type of the input elements
1244      * @param <K> the output type of the key mapping function
1245      * @param <U> the output type of the value mapping function
1246      * @param keyMapper a mapping function to produce keys
1247      * @param valueMapper a mapping function to produce values
1248      * @return a {@code Collector} which collects elements into a {@code Map}
1249      * whose keys and values are the result of applying mapping functions to
1250      * the input elements
1251      *
1252      * @see #toMap(Function, Function, BinaryOperator)
1253      * @see #toMap(Function, Function, BinaryOperator, Supplier)
1254      * @see #toConcurrentMap(Function, Function)
1255      */
1256     public static <T, K, U>
1257     Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
1258                                     Function<? super T, ? extends U> valueMapper) {
1259         return new CollectorImpl<>(HashMap::new,
1260                                    uniqKeysMapAccumulator(keyMapper, valueMapper),
1261                                    uniqKeysMapMerger(),
1262                                    CH_ID);
1263     }
1264 
1265     /**
1266      * Returns a {@code Collector} that accumulates elements into a
1267      * {@code Map} whose keys and values are the result of applying the provided
1268      * mapping functions to the input elements.
1269      *
1270      * <p>If the mapped
1271      * keys contains duplicates (according to {@link Object#equals(Object)}),
1272      * the value mapping function is applied to each equal element, and the
1273      * results are merged using the provided merging function.
1274      *
1275      * @apiNote
1276      * There are multiple ways to deal with collisions between multiple elements
1277      * mapping to the same key.  The other forms of {@code toMap} simply use
1278      * a merge function that throws unconditionally, but you can easily write
1279      * more flexible merge policies.  For example, if you have a stream
1280      * of {@code Person}, and you want to produce a "phone book" mapping name to
1281      * address, but it is possible that two persons have the same name, you can
1282      * do as follows to gracefully deals with these collisions, and produce a
1283      * {@code Map} mapping names to a concatenated list of addresses:
1284      * <pre>{@code
1285      *     Map<String, String> phoneBook
1286      *         people.stream().collect(toMap(Person::getName,
1287      *                                       Person::getAddress,
1288      *                                       (s, a) -> s + ", " + a));
1289      * }</pre>
1290      *
1291      * @implNote
1292      * The returned {@code Collector} is not concurrent.  For parallel stream
1293      * pipelines, the {@code combiner} function operates by merging the keys
1294      * from one map into another, which can be an expensive operation.  If it is
1295      * not required that results are merged into the {@code Map} in encounter
1296      * order, using {@link #toConcurrentMap(Function, Function, BinaryOperator)}
1297      * may offer better parallel performance.
1298      *
1299      * @param <T> the type of the input elements
1300      * @param <K> the output type of the key mapping function
1301      * @param <U> the output type of the value mapping function
1302      * @param keyMapper a mapping function to produce keys
1303      * @param valueMapper a mapping function to produce values
1304      * @param mergeFunction a merge function, used to resolve collisions between
1305      *                      values associated with the same key, as supplied
1306      *                      to {@link Map#merge(Object, Object, BiFunction)}
1307      * @return a {@code Collector} which collects elements into a {@code Map}
1308      * whose keys are the result of applying a key mapping function to the input
1309      * elements, and whose values are the result of applying a value mapping
1310      * function to all input elements equal to the key and combining them
1311      * using the merge function
1312      *
1313      * @see #toMap(Function, Function)
1314      * @see #toMap(Function, Function, BinaryOperator, Supplier)
1315      * @see #toConcurrentMap(Function, Function, BinaryOperator)
1316      */
1317     public static <T, K, U>
1318     Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
1319                                     Function<? super T, ? extends U> valueMapper,
1320                                     BinaryOperator<U> mergeFunction) {
1321         return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
1322     }
1323 
1324     /**
1325      * Returns a {@code Collector} that accumulates elements into a
1326      * {@code Map} whose keys and values are the result of applying the provided
1327      * mapping functions to the input elements.
1328      *
1329      * <p>If the mapped
1330      * keys contains duplicates (according to {@link Object#equals(Object)}),
1331      * the value mapping function is applied to each equal element, and the
1332      * results are merged using the provided merging function.  The {@code Map}
1333      * is created by a provided supplier function.
1334      *
1335      * @implNote
1336      * The returned {@code Collector} is not concurrent.  For parallel stream
1337      * pipelines, the {@code combiner} function operates by merging the keys
1338      * from one map into another, which can be an expensive operation.  If it is
1339      * not required that results are merged into the {@code Map} in encounter
1340      * order, using {@link #toConcurrentMap(Function, Function, BinaryOperator, Supplier)}
1341      * may offer better parallel performance.
1342      *
1343      * @param <T> the type of the input elements
1344      * @param <K> the output type of the key mapping function
1345      * @param <U> the output type of the value mapping function
1346      * @param <M> the type of the resulting {@code Map}
1347      * @param keyMapper a mapping function to produce keys
1348      * @param valueMapper a mapping function to produce values
1349      * @param mergeFunction a merge function, used to resolve collisions between
1350      *                      values associated with the same key, as supplied
1351      *                      to {@link Map#merge(Object, Object, BiFunction)}
1352      * @param mapSupplier a function which returns a new, empty {@code Map} into
1353      *                    which the results will be inserted
1354      * @return a {@code Collector} which collects elements into a {@code Map}
1355      * whose keys are the result of applying a key mapping function to the input
1356      * elements, and whose values are the result of applying a value mapping
1357      * function to all input elements equal to the key and combining them
1358      * using the merge function
1359      *
1360      * @see #toMap(Function, Function)
1361      * @see #toMap(Function, Function, BinaryOperator)
1362      * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
1363      */
1364     public static <T, K, U, M extends Map<K, U>>
1365     Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
1366                                 Function<? super T, ? extends U> valueMapper,
1367                                 BinaryOperator<U> mergeFunction,
1368                                 Supplier<M> mapSupplier) {
1369         BiConsumer<M, T> accumulator
1370                 = (map, element) -> map.merge(keyMapper.apply(element),
1371                                               valueMapper.apply(element), mergeFunction);
1372         return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
1373     }
1374 
1375     /**
1376      * Returns a concurrent {@code Collector} that accumulates elements into a
1377      * {@code ConcurrentMap} whose keys and values are the result of applying
1378      * the provided mapping functions to the input elements.
1379      *
1380      * <p>If the mapped keys contains duplicates (according to
1381      * {@link Object#equals(Object)}), an {@code IllegalStateException} is
1382      * thrown when the collection operation is performed.  If the mapped keys
1383      * may have duplicates, use
1384      * {@link #toConcurrentMap(Function, Function, BinaryOperator)} instead.
1385      *
1386      * @apiNote
1387      * It is common for either the key or the value to be the input elements.
1388      * In this case, the utility method
1389      * {@link java.util.function.Function#identity()} may be helpful.
1390      * For example, the following produces a {@code Map} mapping
1391      * students to their grade point average:
1392      * <pre>{@code
1393      *     Map<Student, Double> studentToGPA
1394      *         students.stream().collect(toMap(Functions.identity(),
1395      *                                         student -> computeGPA(student)));
1396      * }</pre>
1397      * And the following produces a {@code Map} mapping a unique identifier to
1398      * students:
1399      * <pre>{@code
1400      *     Map<String, Student> studentIdToStudent
1401      *         students.stream().collect(toConcurrentMap(Student::getId,
1402      *                                                   Functions.identity());
1403      * }</pre>
1404      *
1405      * <p>This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
1406      * {@link Collector.Characteristics#UNORDERED unordered} Collector.
1407      *
1408      * @param <T> the type of the input elements
1409      * @param <K> the output type of the key mapping function
1410      * @param <U> the output type of the value mapping function
1411      * @param keyMapper the mapping function to produce keys
1412      * @param valueMapper the mapping function to produce values
1413      * @return a concurrent, unordered {@code Collector} which collects elements into a
1414      * {@code ConcurrentMap} whose keys are the result of applying a key mapping
1415      * function to the input elements, and whose values are the result of
1416      * applying a value mapping function to the input elements
1417      *
1418      * @see #toMap(Function, Function)
1419      * @see #toConcurrentMap(Function, Function, BinaryOperator)
1420      * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
1421      */
1422     public static <T, K, U>
1423     Collector<T, ?, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
1424                                                         Function<? super T, ? extends U> valueMapper) {
1425         return new CollectorImpl<>(ConcurrentHashMap::new,
1426                                    uniqKeysMapAccumulator(keyMapper, valueMapper),
1427                                    uniqKeysMapMerger(),
1428                                    CH_CONCURRENT_ID);
1429     }
1430 
1431     /**
1432      * Returns a concurrent {@code Collector} that accumulates elements into a
1433      * {@code ConcurrentMap} whose keys and values are the result of applying
1434      * the provided mapping functions to the input elements.
1435      *
1436      * <p>If the mapped keys contains duplicates (according to {@link Object#equals(Object)}),
1437      * the value mapping function is applied to each equal element, and the
1438      * results are merged using the provided merging function.
1439      *
1440      * @apiNote
1441      * There are multiple ways to deal with collisions between multiple elements
1442      * mapping to the same key.  The other forms of {@code toConcurrentMap} simply use
1443      * a merge function that throws unconditionally, but you can easily write
1444      * more flexible merge policies.  For example, if you have a stream
1445      * of {@code Person}, and you want to produce a "phone book" mapping name to
1446      * address, but it is possible that two persons have the same name, you can
1447      * do as follows to gracefully deals with these collisions, and produce a
1448      * {@code Map} mapping names to a concatenated list of addresses:
1449      * <pre>{@code
1450      *     Map<String, String> phoneBook
1451      *         people.stream().collect(toConcurrentMap(Person::getName,
1452      *                                                 Person::getAddress,
1453      *                                                 (s, a) -> s + ", " + a));
1454      * }</pre>
1455      *
1456      * <p>This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
1457      * {@link Collector.Characteristics#UNORDERED unordered} Collector.
1458      *
1459      * @param <T> the type of the input elements
1460      * @param <K> the output type of the key mapping function
1461      * @param <U> the output type of the value mapping function
1462      * @param keyMapper a mapping function to produce keys
1463      * @param valueMapper a mapping function to produce values
1464      * @param mergeFunction a merge function, used to resolve collisions between
1465      *                      values associated with the same key, as supplied
1466      *                      to {@link Map#merge(Object, Object, BiFunction)}
1467      * @return a concurrent, unordered {@code Collector} which collects elements into a
1468      * {@code ConcurrentMap} whose keys are the result of applying a key mapping
1469      * function to the input elements, and whose values are the result of
1470      * applying a value mapping function to all input elements equal to the key
1471      * and combining them using the merge function
1472      *
1473      * @see #toConcurrentMap(Function, Function)
1474      * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
1475      * @see #toMap(Function, Function, BinaryOperator)
1476      */
1477     public static <T, K, U>
1478     Collector<T, ?, ConcurrentMap<K,U>>
1479     toConcurrentMap(Function<? super T, ? extends K> keyMapper,
1480                     Function<? super T, ? extends U> valueMapper,
1481                     BinaryOperator<U> mergeFunction) {
1482         return toConcurrentMap(keyMapper, valueMapper, mergeFunction, ConcurrentHashMap::new);
1483     }
1484 
1485     /**
1486      * Returns a concurrent {@code Collector} that accumulates elements into a
1487      * {@code ConcurrentMap} whose keys and values are the result of applying
1488      * the provided mapping functions to the input elements.
1489      *
1490      * <p>If the mapped keys contains duplicates (according to {@link Object#equals(Object)}),
1491      * the value mapping function is applied to each equal element, and the
1492      * results are merged using the provided merging function.  The
1493      * {@code ConcurrentMap} is created by a provided supplier function.
1494      *
1495      * <p>This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
1496      * {@link Collector.Characteristics#UNORDERED unordered} Collector.
1497      *
1498      * @param <T> the type of the input elements
1499      * @param <K> the output type of the key mapping function
1500      * @param <U> the output type of the value mapping function
1501      * @param <M> the type of the resulting {@code ConcurrentMap}
1502      * @param keyMapper a mapping function to produce keys
1503      * @param valueMapper a mapping function to produce values
1504      * @param mergeFunction a merge function, used to resolve collisions between
1505      *                      values associated with the same key, as supplied
1506      *                      to {@link Map#merge(Object, Object, BiFunction)}
1507      * @param mapSupplier a function which returns a new, empty {@code Map} into
1508      *                    which the results will be inserted
1509      * @return a concurrent, unordered {@code Collector} which collects elements into a
1510      * {@code ConcurrentMap} whose keys are the result of applying a key mapping
1511      * function to the input elements, and whose values are the result of
1512      * applying a value mapping function to all input elements equal to the key
1513      * and combining them using the merge function
1514      *
1515      * @see #toConcurrentMap(Function, Function)
1516      * @see #toConcurrentMap(Function, Function, BinaryOperator)
1517      * @see #toMap(Function, Function, BinaryOperator, Supplier)
1518      */
1519     public static <T, K, U, M extends ConcurrentMap<K, U>>
1520     Collector<T, ?, M> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
1521                                        Function<? super T, ? extends U> valueMapper,
1522                                        BinaryOperator<U> mergeFunction,
1523                                        Supplier<M> mapSupplier) {
1524         BiConsumer<M, T> accumulator
1525                 = (map, element) -> map.merge(keyMapper.apply(element),
1526                                               valueMapper.apply(element), mergeFunction);
1527         return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_CONCURRENT_ID);
1528     }
1529 
1530     /**
1531      * Returns a {@code Collector} which applies an {@code int}-producing
1532      * mapping function to each input element, and returns summary statistics
1533      * for the resulting values.
1534      *
1535      * @param <T> the type of the input elements
1536      * @param mapper a mapping function to apply to each element
1537      * @return a {@code Collector} implementing the summary-statistics reduction
1538      *
1539      * @see #summarizingDouble(ToDoubleFunction)
1540      * @see #summarizingLong(ToLongFunction)
1541      */
1542     public static <T>
1543     Collector<T, ?, IntSummaryStatistics> summarizingInt(ToIntFunction<? super T> mapper) {
1544         return new CollectorImpl<T, IntSummaryStatistics, IntSummaryStatistics>(
1545                 IntSummaryStatistics::new,
1546                 (r, t) -> r.accept(mapper.applyAsInt(t)),
1547                 (l, r) -> { l.combine(r); return l; }, CH_ID);
1548     }
1549 
1550     /**
1551      * Returns a {@code Collector} which applies an {@code long}-producing
1552      * mapping function to each input element, and returns summary statistics
1553      * for the resulting values.
1554      *
1555      * @param <T> the type of the input elements
1556      * @param mapper the mapping function to apply to each element
1557      * @return a {@code Collector} implementing the summary-statistics reduction
1558      *
1559      * @see #summarizingDouble(ToDoubleFunction)
1560      * @see #summarizingInt(ToIntFunction)
1561      */
1562     public static <T>
1563     Collector<T, ?, LongSummaryStatistics> summarizingLong(ToLongFunction<? super T> mapper) {
1564         return new CollectorImpl<T, LongSummaryStatistics, LongSummaryStatistics>(
1565                 LongSummaryStatistics::new,
1566                 (r, t) -> r.accept(mapper.applyAsLong(t)),
1567                 (l, r) -> { l.combine(r); return l; }, CH_ID);
1568     }
1569 
1570     /**
1571      * Returns a {@code Collector} which applies an {@code double}-producing
1572      * mapping function to each input element, and returns summary statistics
1573      * for the resulting values.
1574      *
1575      * @param <T> the type of the input elements
1576      * @param mapper a mapping function to apply to each element
1577      * @return a {@code Collector} implementing the summary-statistics reduction
1578      *
1579      * @see #summarizingLong(ToLongFunction)
1580      * @see #summarizingInt(ToIntFunction)
1581      */
1582     public static <T>
1583     Collector<T, ?, DoubleSummaryStatistics> summarizingDouble(ToDoubleFunction<? super T> mapper) {
1584         return new CollectorImpl<T, DoubleSummaryStatistics, DoubleSummaryStatistics>(
1585                 DoubleSummaryStatistics::new,
1586                 (r, t) -> r.accept(mapper.applyAsDouble(t)),
1587                 (l, r) -> { l.combine(r); return l; }, CH_ID);
1588     }
1589 
1590     /**
1591      * Implementation class used by partitioningBy.
1592      */
1593     private static final class Partition<T>
1594             extends AbstractMap<Boolean, T>
1595             implements Map<Boolean, T> {
1596         final T forTrue;
1597         final T forFalse;
1598 
1599         Partition(T forTrue, T forFalse) {
1600             this.forTrue = forTrue;
1601             this.forFalse = forFalse;
1602         }
1603 
1604         @Override
1605         public Set<Map.Entry<Boolean, T>> entrySet() {
1606             return new AbstractSet<Map.Entry<Boolean, T>>() {
1607                 @Override
1608                 public Iterator<Map.Entry<Boolean, T>> iterator() {
1609                     Map.Entry<Boolean, T> falseEntry = new SimpleImmutableEntry<>(false, forFalse);
1610                     Map.Entry<Boolean, T> trueEntry = new SimpleImmutableEntry<>(true, forTrue);
1611                     return Arrays.asList(falseEntry, trueEntry).iterator();
1612                 }
1613 
1614                 @Override
1615                 public int size() {
1616                     return 2;
1617                 }
1618             };
1619         }
1620     }
1621 }