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