jdk/src/share/classes/java/util/stream/Collectors.java
changeset 19214 e5901820c3c1
parent 18571 8e3cb3c46ae8
child 19420 a95fae98f735
equal deleted inserted replaced
19213:c360667a0da2 19214:e5901820c3c1
    25 package java.util.stream;
    25 package java.util.stream;
    26 
    26 
    27 import java.util.AbstractMap;
    27 import java.util.AbstractMap;
    28 import java.util.AbstractSet;
    28 import java.util.AbstractSet;
    29 import java.util.ArrayList;
    29 import java.util.ArrayList;
       
    30 import java.util.Arrays;
    30 import java.util.Collection;
    31 import java.util.Collection;
    31 import java.util.Collections;
    32 import java.util.Collections;
    32 import java.util.Comparator;
    33 import java.util.Comparator;
    33 import java.util.DoubleSummaryStatistics;
    34 import java.util.DoubleSummaryStatistics;
    34 import java.util.EnumSet;
    35 import java.util.EnumSet;
    37 import java.util.IntSummaryStatistics;
    38 import java.util.IntSummaryStatistics;
    38 import java.util.Iterator;
    39 import java.util.Iterator;
    39 import java.util.List;
    40 import java.util.List;
    40 import java.util.LongSummaryStatistics;
    41 import java.util.LongSummaryStatistics;
    41 import java.util.Map;
    42 import java.util.Map;
    42 import java.util.NoSuchElementException;
       
    43 import java.util.Objects;
    43 import java.util.Objects;
       
    44 import java.util.Optional;
    44 import java.util.Set;
    45 import java.util.Set;
    45 import java.util.StringJoiner;
    46 import java.util.StringJoiner;
    46 import java.util.concurrent.ConcurrentHashMap;
    47 import java.util.concurrent.ConcurrentHashMap;
    47 import java.util.concurrent.ConcurrentMap;
    48 import java.util.concurrent.ConcurrentMap;
       
    49 import java.util.function.BiConsumer;
    48 import java.util.function.BiFunction;
    50 import java.util.function.BiFunction;
    49 import java.util.function.BinaryOperator;
    51 import java.util.function.BinaryOperator;
       
    52 import java.util.function.Consumer;
    50 import java.util.function.Function;
    53 import java.util.function.Function;
    51 import java.util.function.Predicate;
    54 import java.util.function.Predicate;
    52 import java.util.function.Supplier;
    55 import java.util.function.Supplier;
    53 import java.util.function.ToDoubleFunction;
    56 import java.util.function.ToDoubleFunction;
    54 import java.util.function.ToIntFunction;
    57 import java.util.function.ToIntFunction;
    62  * <p>The following are examples of using the predefined {@code Collector}
    65  * <p>The following are examples of using the predefined {@code Collector}
    63  * implementations in {@link Collectors} with the {@code Stream} API to perform
    66  * implementations in {@link Collectors} with the {@code Stream} API to perform
    64  * mutable reduction tasks:
    67  * mutable reduction tasks:
    65  *
    68  *
    66  * <pre>{@code
    69  * <pre>{@code
    67  *     // Accumulate elements into a List
    70  *     // Accumulate names into a List
    68  *     List<Person> list = people.collect(Collectors.toList());
    71  *     List<String> list = people.stream().map(Person::getName).collect(Collectors.toList());
    69  *
    72  *
    70  *     // Accumulate elements into a TreeSet
    73  *     // Accumulate names into a TreeSet
    71  *     List<Person> list = people.collect(Collectors.toCollection(TreeSet::new));
    74  *     Set<String> list = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));
    72  *
    75  *
    73  *     // Convert elements to strings and concatenate them, separated by commas
    76  *     // Convert elements to strings and concatenate them, separated by commas
    74  *     String joined = stream.map(Object::toString)
    77  *     String joined = things.stream()
    75  *                           .collect(Collectors.toStringJoiner(", "))
    78  *                           .map(Object::toString)
    76  *                           .toString();
    79  *                           .collect(Collectors.joining(", "));
    77  *
    80  *
    78  *     // Find highest-paid employee
    81  *     // Find highest-paid employee
    79  *     Employee highestPaid = employees.stream()
    82  *     Employee highestPaid = employees.stream()
    80  *                                     .collect(Collectors.maxBy(Comparator.comparing(Employee::getSalary)));
    83  *                                     .collect(Collectors.maxBy(Comparator.comparing(Employee::getSalary)))
       
    84  *                                     .get();
    81  *
    85  *
    82  *     // Group employees by department
    86  *     // Group employees by department
    83  *     Map<Department, List<Employee>> byDept
    87  *     Map<Department, List<Employee>> byDept
    84  *         = employees.stream()
    88  *         = employees.stream()
    85  *                    .collect(Collectors.groupingBy(Employee::getDepartment));
    89  *                    .collect(Collectors.groupingBy(Employee::getDepartment));
    86  *
    90  *
    87  *     // Find highest-paid employee by department
    91  *     // Find highest-paid employee by department
    88  *     Map<Department, Employee> highestPaidByDept
    92  *     Map<Department, Optional<Employee>> highestPaidByDept
    89  *         = employees.stream()
    93  *         = employees.stream()
    90  *                    .collect(Collectors.groupingBy(Employee::getDepartment,
    94  *                    .collect(Collectors.groupingBy(Employee::getDepartment,
    91  *                                                   Collectors.maxBy(Comparator.comparing(Employee::getSalary))));
    95  *                                                   Collectors.maxBy(Comparator.comparing(Employee::getSalary))));
    92  *
    96  *
    93  *     // Partition students into passing and failing
    97  *     // Partition students into passing and failing
    94  *     Map<Boolean, List<Student>> passingFailing =
    98  *     Map<Boolean, List<Student>> passingFailing =
    95  *         students.stream()
    99  *         students.stream()
    96  *                 .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD);
   100  *                 .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
    97  *
   101  *
    98  * }</pre>
   102  * }</pre>
    99  *
   103  *
   100  * TODO explanation of parallel collection
   104  * TODO explanation of parallel collection
   101  *
   105  *
   102  * @since 1.8
   106  * @since 1.8
   103  */
   107  */
   104 public final class Collectors {
   108 public final class Collectors {
   105 
   109 
   106     private static final Set<Collector.Characteristics> CH_CONCURRENT
   110     static final Set<Collector.Characteristics> CH_CONCURRENT_ID
   107             = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.CONCURRENT,
   111             = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.CONCURRENT,
   108                                                      Collector.Characteristics.STRICTLY_MUTATIVE,
   112                                                      Collector.Characteristics.UNORDERED,
       
   113                                                      Collector.Characteristics.IDENTITY_FINISH));
       
   114     static final Set<Collector.Characteristics> CH_CONCURRENT_NOID
       
   115             = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.CONCURRENT,
   109                                                      Collector.Characteristics.UNORDERED));
   116                                                      Collector.Characteristics.UNORDERED));
   110     private static final Set<Collector.Characteristics> CH_STRICT
   117     static final Set<Collector.Characteristics> CH_ID
   111             = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.STRICTLY_MUTATIVE));
   118             = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH));
   112     private static final Set<Collector.Characteristics> CH_STRICT_UNORDERED
   119     static final Set<Collector.Characteristics> CH_UNORDERED_ID
   113             = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.STRICTLY_MUTATIVE,
   120             = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.UNORDERED,
   114                                                      Collector.Characteristics.UNORDERED));
   121                                                      Collector.Characteristics.IDENTITY_FINISH));
       
   122     static final Set<Collector.Characteristics> CH_NOID = Collections.emptySet();
   115 
   123 
   116     private Collectors() { }
   124     private Collectors() { }
   117 
   125 
   118     /**
   126     /**
   119      * Returns a merge function, suitable for use in
   127      * Returns a merge function, suitable for use in
   122      * throws {@code IllegalStateException}.  This can be used to enforce the
   130      * throws {@code IllegalStateException}.  This can be used to enforce the
   123      * assumption that the elements being collected are distinct.
   131      * assumption that the elements being collected are distinct.
   124      *
   132      *
   125      * @param <T> the type of input arguments to the merge function
   133      * @param <T> the type of input arguments to the merge function
   126      * @return a merge function which always throw {@code IllegalStateException}
   134      * @return a merge function which always throw {@code IllegalStateException}
   127      *
   135      */
   128      * @see #firstWinsMerger()
   136     private static <T> BinaryOperator<T> throwingMerger() {
   129      * @see #lastWinsMerger()
       
   130      */
       
   131     public static <T> BinaryOperator<T> throwingMerger() {
       
   132         return (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); };
   137         return (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); };
   133     }
       
   134 
       
   135     /**
       
   136      * Returns a merge function, suitable for use in
       
   137      * {@link Map#merge(Object, Object, BiFunction) Map.merge()} or
       
   138      * {@link #toMap(Function, Function, BinaryOperator) toMap()},
       
   139      * which implements a "first wins" policy.
       
   140      *
       
   141      * @param <T> the type of input arguments to the merge function
       
   142      * @return a merge function which always returns its first argument
       
   143      * @see #lastWinsMerger()
       
   144      * @see #throwingMerger()
       
   145      */
       
   146     public static <T> BinaryOperator<T> firstWinsMerger() {
       
   147         return (u,v) -> u;
       
   148     }
       
   149 
       
   150     /**
       
   151      * Returns a merge function, suitable for use in
       
   152      * {@link Map#merge(Object, Object, BiFunction) Map.merge()} or
       
   153      * {@link #toMap(Function, Function, BinaryOperator) toMap()},
       
   154      * which implements a "last wins" policy.
       
   155      *
       
   156      * @param <T> the type of input arguments to the merge function
       
   157      * @return a merge function which always returns its second argument
       
   158      * @see #firstWinsMerger()
       
   159      * @see #throwingMerger()
       
   160      */
       
   161     public static <T> BinaryOperator<T> lastWinsMerger() {
       
   162         return (u,v) -> v;
       
   163     }
   138     }
   164 
   139 
   165     /**
   140     /**
   166      * Simple implementation class for {@code Collector}.
   141      * Simple implementation class for {@code Collector}.
   167      *
   142      *
   168      * @param <T> the type of elements to be collected
   143      * @param <T> the type of elements to be collected
   169      * @param <R> the type of the result
   144      * @param <R> the type of the result
   170      */
   145      */
   171     private static final class CollectorImpl<T, R> implements Collector<T,R> {
   146     static class CollectorImpl<T, A, R> implements Collector<T, A, R> {
   172         private final Supplier<R> resultSupplier;
   147         private final Supplier<A> supplier;
   173         private final BiFunction<R, T, R> accumulator;
   148         private final BiConsumer<A, T> accumulator;
   174         private final BinaryOperator<R> combiner;
   149         private final BinaryOperator<A> combiner;
       
   150         private final Function<A, R> finisher;
   175         private final Set<Characteristics> characteristics;
   151         private final Set<Characteristics> characteristics;
   176 
   152 
   177         CollectorImpl(Supplier<R> resultSupplier,
   153         CollectorImpl(Supplier<A> supplier,
   178                       BiFunction<R, T, R> accumulator,
   154                       BiConsumer<A, T> accumulator,
   179                       BinaryOperator<R> combiner,
   155                       BinaryOperator<A> combiner,
       
   156                       Function<A,R> finisher,
   180                       Set<Characteristics> characteristics) {
   157                       Set<Characteristics> characteristics) {
   181             this.resultSupplier = resultSupplier;
   158             this.supplier = supplier;
   182             this.accumulator = accumulator;
   159             this.accumulator = accumulator;
   183             this.combiner = combiner;
   160             this.combiner = combiner;
       
   161             this.finisher = finisher;
   184             this.characteristics = characteristics;
   162             this.characteristics = characteristics;
   185         }
   163         }
   186 
   164 
   187         CollectorImpl(Supplier<R> resultSupplier,
   165         CollectorImpl(Supplier<A> supplier,
   188                       BiFunction<R, T, R> accumulator,
   166                       BiConsumer<A, T> accumulator,
   189                       BinaryOperator<R> combiner) {
   167                       BinaryOperator<A> combiner,
   190             this(resultSupplier, accumulator, combiner, Collections.emptySet());
   168                       Set<Characteristics> characteristics) {
       
   169             this(supplier, accumulator, combiner, i -> (R) i, characteristics);
   191         }
   170         }
   192 
   171 
   193         @Override
   172         @Override
   194         public BiFunction<R, T, R> accumulator() {
   173         public BiConsumer<A, T> accumulator() {
   195             return accumulator;
   174             return accumulator;
   196         }
   175         }
   197 
   176 
   198         @Override
   177         @Override
   199         public Supplier<R> resultSupplier() {
   178         public Supplier<A> supplier() {
   200             return resultSupplier;
   179             return supplier;
   201         }
   180         }
   202 
   181 
   203         @Override
   182         @Override
   204         public BinaryOperator<R> combiner() {
   183         public BinaryOperator<A> combiner() {
   205             return combiner;
   184             return combiner;
       
   185         }
       
   186 
       
   187         @Override
       
   188         public Function<A, R> finisher() {
       
   189             return finisher;
   206         }
   190         }
   207 
   191 
   208         @Override
   192         @Override
   209         public Set<Characteristics> characteristics() {
   193         public Set<Characteristics> characteristics() {
   210             return characteristics;
   194             return characteristics;
   222      * {@code Collection} of the appropriate type
   206      * {@code Collection} of the appropriate type
   223      * @return a {@code Collector} which collects all the input elements into a
   207      * @return a {@code Collector} which collects all the input elements into a
   224      * {@code Collection}, in encounter order
   208      * {@code Collection}, in encounter order
   225      */
   209      */
   226     public static <T, C extends Collection<T>>
   210     public static <T, C extends Collection<T>>
   227     Collector<T, C> toCollection(Supplier<C> collectionFactory) {
   211     Collector<T, ?, C> toCollection(Supplier<C> collectionFactory) {
   228         return new CollectorImpl<>(collectionFactory,
   212         return new CollectorImpl<>(collectionFactory, Collection::add,
   229                                    (r, t) -> { r.add(t); return r; },
       
   230                                    (r1, r2) -> { r1.addAll(r2); return r1; },
   213                                    (r1, r2) -> { r1.addAll(r2); return r1; },
   231                                    CH_STRICT);
   214                                    CH_ID);
   232     }
   215     }
   233 
   216 
   234     /**
   217     /**
   235      * Returns a {@code Collector} that accumulates the input elements into a
   218      * Returns a {@code Collector} that accumulates the input elements into a
   236      * new {@code List}. There are no guarantees on the type, mutability,
   219      * new {@code List}. There are no guarantees on the type, mutability,
   239      * @param <T> the type of the input elements
   222      * @param <T> the type of the input elements
   240      * @return a {@code Collector} which collects all the input elements into a
   223      * @return a {@code Collector} which collects all the input elements into a
   241      * {@code List}, in encounter order
   224      * {@code List}, in encounter order
   242      */
   225      */
   243     public static <T>
   226     public static <T>
   244     Collector<T, List<T>> toList() {
   227     Collector<T, ?, List<T>> toList() {
   245         BiFunction<List<T>, T, List<T>> accumulator = (list, t) -> {
   228         return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
   246             switch (list.size()) {
   229                                    (left, right) -> { left.addAll(right); return left; },
   247                 case 0:
   230                                    CH_ID);
   248                     return Collections.singletonList(t);
       
   249                 case 1:
       
   250                     List<T> newList = new ArrayList<>();
       
   251                     newList.add(list.get(0));
       
   252                     newList.add(t);
       
   253                     return newList;
       
   254                 default:
       
   255                     list.add(t);
       
   256                     return list;
       
   257             }
       
   258         };
       
   259         BinaryOperator<List<T>> combiner = (left, right) -> {
       
   260             switch (left.size()) {
       
   261                 case 0:
       
   262                     return right;
       
   263                 case 1:
       
   264                     List<T> newList = new ArrayList<>(left.size() + right.size());
       
   265                     newList.addAll(left);
       
   266                     newList.addAll(right);
       
   267                     return newList;
       
   268                 default:
       
   269                     left.addAll(right);
       
   270                     return left;
       
   271             }
       
   272         };
       
   273         return new CollectorImpl<>(Collections::emptyList, accumulator, combiner);
       
   274     }
   231     }
   275 
   232 
   276     /**
   233     /**
   277      * Returns a {@code Collector} that accumulates the input elements into a
   234      * Returns a {@code Collector} that accumulates the input elements into a
   278      * new {@code Set}. There are no guarantees on the type, mutability,
   235      * new {@code Set}. There are no guarantees on the type, mutability,
   284      * @param <T> the type of the input elements
   241      * @param <T> the type of the input elements
   285      * @return a {@code Collector} which collects all the input elements into a
   242      * @return a {@code Collector} which collects all the input elements into a
   286      * {@code Set}
   243      * {@code Set}
   287      */
   244      */
   288     public static <T>
   245     public static <T>
   289     Collector<T, Set<T>> toSet() {
   246     Collector<T, ?, Set<T>> toSet() {
   290         return new CollectorImpl<>((Supplier<Set<T>>) HashSet::new,
   247         return new CollectorImpl<>((Supplier<Set<T>>) HashSet::new, Set::add,
   291                                    (r, t) -> { r.add(t); return r; },
   248                                    (left, right) -> { left.addAll(right); return left; },
   292                                    (r1, r2) -> { r1.addAll(r2); return r1; },
   249                                    CH_UNORDERED_ID);
   293                                    CH_STRICT_UNORDERED);
       
   294     }
   250     }
   295 
   251 
   296     /**
   252     /**
   297      * Returns a {@code Collector} that concatenates the input elements into a
   253      * Returns a {@code Collector} that concatenates the input elements into a
   298      * new {@link StringBuilder}.
   254      * {@code String}, in encounter order.
   299      *
   255      *
   300      * @return a {@code Collector} which collects String elements into a
   256      * @return a {@code Collector} that concatenates the input elements into a
   301      * {@code StringBuilder}, in encounter order
   257      * {@code String}, in encounter order
   302      */
   258      */
   303     public static Collector<String, StringBuilder> toStringBuilder() {
   259     public static Collector<CharSequence, ?, String> joining() {
   304         return new CollectorImpl<>(StringBuilder::new,
   260         return new CollectorImpl<CharSequence, StringBuilder, String>(
   305                                    (r, t) -> { r.append(t); return r; },
   261                 StringBuilder::new, StringBuilder::append,
   306                                    (r1, r2) -> { r1.append(r2); return r1; },
   262                 (r1, r2) -> { r1.append(r2); return r1; },
   307                                    CH_STRICT);
   263                 StringBuilder::toString, CH_NOID);
   308     }
   264     }
   309 
   265 
   310     /**
   266     /**
   311      * Returns a {@code Collector} that concatenates the input elements into a
   267      * Returns a {@code Collector} that concatenates the input elements,
   312      * new {@link StringJoiner}, using the specified delimiter.
   268      * separated by the specified delimiter, in encounter order.
   313      *
   269      *
   314      * @param delimiter the delimiter to be used between each element
   270      * @param delimiter the delimiter to be used between each element
   315      * @return A {@code Collector} which collects String elements into a
   271      * @return A {@code Collector} which concatenates CharSequence elements,
   316      * {@code StringJoiner}, in encounter order
   272      * separated by the specified delimiter, in encounter order
   317      */
   273      */
   318     public static Collector<CharSequence, StringJoiner> toStringJoiner(CharSequence delimiter) {
   274     public static Collector<CharSequence, ?, String> joining(CharSequence delimiter) {
   319         BinaryOperator<StringJoiner> merger = (sj, other) -> {
   275         return joining(delimiter, "", "");
   320             if (other.length() > 0)
   276     }
   321                 sj.add(other.toString());
   277 
   322             return sj;
   278     /**
   323         };
   279      * Returns a {@code Collector} that concatenates the input elements,
   324         return new CollectorImpl<>(() -> new StringJoiner(delimiter),
   280      * separated by the specified delimiter, with the specified prefix and
   325                                    (r, t) -> { r.add(t); return r; },
   281      * suffix, in encounter order.
   326                                    merger, CH_STRICT);
   282      *
       
   283      * @param delimiter the delimiter to be used between each element
       
   284      * @param  prefix the sequence of characters to be used at the beginning
       
   285      *                of the joined result
       
   286      * @param  suffix the sequence of characters to be used at the end
       
   287      *                of the joined result
       
   288      * @return A {@code Collector} which concatenates CharSequence elements,
       
   289      * separated by the specified delimiter, in encounter order
       
   290      */
       
   291     public static Collector<CharSequence, ?, String> joining(CharSequence delimiter,
       
   292                                                              CharSequence prefix,
       
   293                                                              CharSequence suffix) {
       
   294         return new CollectorImpl<>(
       
   295                 () -> new StringJoiner(delimiter, prefix, suffix),
       
   296                 StringJoiner::add, StringJoiner::merge,
       
   297                 StringJoiner::toString, CH_NOID);
   327     }
   298     }
   328 
   299 
   329     /**
   300     /**
   330      * {@code BinaryOperator<Map>} that merges the contents of its right
   301      * {@code BinaryOperator<Map>} that merges the contents of its right
   331      * argument into its left argument, using the provided merge function to
   302      * argument into its left argument, using the provided merge function to
   346             return m1;
   317             return m1;
   347         };
   318         };
   348     }
   319     }
   349 
   320 
   350     /**
   321     /**
   351      * Adapts a {@code Collector<U,R>} to a {@code Collector<T,R>} by applying
   322      * Adapts a {@code Collector} accepting elements of type {@code U} to one
   352      * a mapping function to each input element before accumulation.
   323      * accepting elements of type {@code T} by applying a mapping function to
       
   324      * each input element before accumulation.
   353      *
   325      *
   354      * @apiNote
   326      * @apiNote
   355      * The {@code mapping()} collectors are most useful when used in a
   327      * The {@code mapping()} collectors are most useful when used in a
   356      * multi-level reduction, downstream of {@code groupingBy} or
   328      * multi-level reduction, such as downstream of a {@code groupingBy} or
   357      * {@code partitioningBy}.  For example, given a stream of
   329      * {@code partitioningBy}.  For example, given a stream of
   358      * {@code Person}, to accumulate the set of last names in each city:
   330      * {@code Person}, to accumulate the set of last names in each city:
   359      * <pre>{@code
   331      * <pre>{@code
   360      *     Map<City, Set<String>> lastNamesByCity
   332      *     Map<City, Set<String>> lastNamesByCity
   361      *         = people.stream().collect(groupingBy(Person::getCity,
   333      *         = people.stream().collect(groupingBy(Person::getCity,
   362      *                                              mapping(Person::getLastName, toSet())));
   334      *                                              mapping(Person::getLastName, toSet())));
   363      * }</pre>
   335      * }</pre>
   364      *
   336      *
   365      * @param <T> the type of the input elements
   337      * @param <T> the type of the input elements
   366      * @param <U> type of elements accepted by downstream collector
   338      * @param <U> type of elements accepted by downstream collector
       
   339      * @param <A> intermediate accumulation type of the downstream collector
   367      * @param <R> result type of collector
   340      * @param <R> result type of collector
   368      * @param mapper a function to be applied to the input elements
   341      * @param mapper a function to be applied to the input elements
   369      * @param downstream a collector which will accept mapped values
   342      * @param downstream a collector which will accept mapped values
   370      * @return a collector which applies the mapping function to the input
   343      * @return a collector which applies the mapping function to the input
   371      * elements and provides the mapped results to the downstream collector
   344      * elements and provides the mapped results to the downstream collector
   372      */
   345      */
   373     public static <T, U, R> Collector<T, R>
   346     public static <T, U, A, R>
   374     mapping(Function<? super T, ? extends U> mapper, Collector<? super U, R> downstream) {
   347     Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper,
   375         BiFunction<R, ? super U, R> downstreamAccumulator = downstream.accumulator();
   348                                Collector<? super U, A, R> downstream) {
   376         return new CollectorImpl<>(downstream.resultSupplier(),
   349         BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
   377                                    (r, t) -> downstreamAccumulator.apply(r, mapper.apply(t)),
   350         return new CollectorImpl<>(downstream.supplier(),
   378                                    downstream.combiner(), downstream.characteristics());
   351                                    (r, t) -> downstreamAccumulator.accept(r, mapper.apply(t)),
   379     }
   352                                    downstream.combiner(), downstream.finisher(),
   380 
   353                                    downstream.characteristics());
   381     /**
   354     }
   382      * Returns a {@code Collector<T, Long>} that counts the number of input
   355 
   383      * elements.
   356     /**
       
   357      * Returns a {@code Collector} accepting elements of type {@code T} that
       
   358      * counts the number of input elements.  If no elements are present, the
       
   359      * result is 0.
   384      *
   360      *
   385      * @implSpec
   361      * @implSpec
   386      * This produces a result equivalent to:
   362      * This produces a result equivalent to:
   387      * <pre>{@code
   363      * <pre>{@code
   388      *     reducing(0L, e -> 1L, Long::sum)
   364      *     reducing(0L, e -> 1L, Long::sum)
   389      * }</pre>
   365      * }</pre>
   390      *
   366      *
   391      * @param <T> the type of the input elements
   367      * @param <T> the type of the input elements
   392      * @return a {@code Collector} that counts the input elements
   368      * @return a {@code Collector} that counts the input elements
   393      */
   369      */
   394     public static <T> Collector<T, Long>
   370     public static <T> Collector<T, ?, Long>
   395     counting() {
   371     counting() {
   396         return reducing(0L, e -> 1L, Long::sum);
   372         return reducing(0L, e -> 1L, Long::sum);
   397     }
   373     }
   398 
   374 
   399     /**
   375     /**
   400      * Returns a {@code Collector<T, T>} that produces the minimal element
   376      * Returns a {@code Collector} that produces the minimal element according
   401      * according to a given {@code Comparator}.
   377      * to a given {@code Comparator}, described as an {@code Optional<T>}.
   402      *
   378      *
   403      * @implSpec
   379      * @implSpec
   404      * This produces a result equivalent to:
   380      * This produces a result equivalent to:
   405      * <pre>{@code
   381      * <pre>{@code
   406      *     reducing(BinaryOperator.minBy(comparator))
   382      *     reducing(BinaryOperator.minBy(comparator))
   408      *
   384      *
   409      * @param <T> the type of the input elements
   385      * @param <T> the type of the input elements
   410      * @param comparator a {@code Comparator} for comparing elements
   386      * @param comparator a {@code Comparator} for comparing elements
   411      * @return a {@code Collector} that produces the minimal value
   387      * @return a {@code Collector} that produces the minimal value
   412      */
   388      */
   413     public static <T> Collector<T, T>
   389     public static <T> Collector<T, ?, Optional<T>>
   414     minBy(Comparator<? super T> comparator) {
   390     minBy(Comparator<? super T> comparator) {
   415         return reducing(BinaryOperator.minBy(comparator));
   391         return reducing(BinaryOperator.minBy(comparator));
   416     }
   392     }
   417 
   393 
   418     /**
   394     /**
   419      * Returns a {@code Collector<T, T>} that produces the maximal element
   395      * Returns a {@code Collector} that produces the maximal element according
   420      * according to a given {@code Comparator}.
   396      * to a given {@code Comparator}, described as an {@code Optional<T>}.
   421      *
   397      *
   422      * @implSpec
   398      * @implSpec
   423      * This produces a result equivalent to:
   399      * This produces a result equivalent to:
   424      * <pre>{@code
   400      * <pre>{@code
   425      *     reducing(BinaryOperator.maxBy(comparator))
   401      *     reducing(BinaryOperator.maxBy(comparator))
   427      *
   403      *
   428      * @param <T> the type of the input elements
   404      * @param <T> the type of the input elements
   429      * @param comparator a {@code Comparator} for comparing elements
   405      * @param comparator a {@code Comparator} for comparing elements
   430      * @return a {@code Collector} that produces the maximal value
   406      * @return a {@code Collector} that produces the maximal value
   431      */
   407      */
   432     public static <T> Collector<T, T>
   408     public static <T> Collector<T, ?, Optional<T>>
   433     maxBy(Comparator<? super T> comparator) {
   409     maxBy(Comparator<? super T> comparator) {
   434         return reducing(BinaryOperator.maxBy(comparator));
   410         return reducing(BinaryOperator.maxBy(comparator));
   435     }
   411     }
   436 
   412 
   437     /**
   413     /**
   438      * Returns a {@code Collector<T, Long>} that produces the sum of a
   414      * Returns a {@code Collector} that produces the sum of a integer-valued
   439      * long-valued function applied to the input element.
   415      * function applied to the input elements.  If no elements are present,
   440      *
   416      * the result is 0.
   441      * @implSpec
       
   442      * This produces a result equivalent to:
       
   443      * <pre>{@code
       
   444      *     reducing(0L, mapper, Long::sum)
       
   445      * }</pre>
       
   446      *
   417      *
   447      * @param <T> the type of the input elements
   418      * @param <T> the type of the input elements
   448      * @param mapper a function extracting the property to be summed
   419      * @param mapper a function extracting the property to be summed
   449      * @return a {@code Collector} that produces the sum of a derived property
   420      * @return a {@code Collector} that produces the sum of a derived property
   450      */
   421      */
   451     public static <T> Collector<T, Long>
   422     public static <T> Collector<T, ?, Integer>
   452     sumBy(Function<? super T, Long> mapper) {
   423     summingInt(ToIntFunction<? super T> mapper) {
   453         return reducing(0L, mapper, Long::sum);
   424         return new CollectorImpl<T, int[], Integer>(
   454     }
   425                 () -> new int[1],
   455 
   426                 (a, t) -> { a[0] += mapper.applyAsInt(t); },
   456     /**
   427                 (a, b) -> { a[0] += b[0]; return a; },
   457      * Returns a {@code Collector<T,T>} which performs a reduction of its
   428                 a -> a[0], CH_NOID);
   458      * input elements under a specified {@code BinaryOperator}.
   429     }
       
   430 
       
   431     /**
       
   432      * Returns a {@code Collector} that produces the sum of a long-valued
       
   433      * function applied to the input elements.  If no elements are present,
       
   434      * the result is 0.
       
   435      *
       
   436      * @param <T> the type of the input elements
       
   437      * @param mapper a function extracting the property to be summed
       
   438      * @return a {@code Collector} that produces the sum of a derived property
       
   439      */
       
   440     public static <T> Collector<T, ?, Long>
       
   441     summingLong(ToLongFunction<? super T> mapper) {
       
   442         return new CollectorImpl<T, long[], Long>(
       
   443                 () -> new long[1],
       
   444                 (a, t) -> { a[0] += mapper.applyAsLong(t); },
       
   445                 (a, b) -> { a[0] += b[0]; return a; },
       
   446                 a -> a[0], CH_NOID);
       
   447     }
       
   448 
       
   449     /**
       
   450      * Returns a {@code Collector} that produces the sum of a double-valued
       
   451      * function applied to the input elements.  If no elements are present,
       
   452      * the result is 0.
       
   453      *
       
   454      * <p>The sum returned can vary depending upon the order in which
       
   455      * values are recorded, due to accumulated rounding error in
       
   456      * addition of values of differing magnitudes. Values sorted by increasing
       
   457      * absolute magnitude tend to yield more accurate results.  If any recorded
       
   458      * value is a {@code NaN} or the sum is at any point a {@code NaN} then the
       
   459      * sum will be {@code NaN}.
       
   460      *
       
   461      * @param <T> the type of the input elements
       
   462      * @param mapper a function extracting the property to be summed
       
   463      * @return a {@code Collector} that produces the sum of a derived property
       
   464      */
       
   465     public static <T> Collector<T, ?, Double>
       
   466     summingDouble(ToDoubleFunction<? super T> mapper) {
       
   467         return new CollectorImpl<T, double[], Double>(
       
   468                 () -> new double[1],
       
   469                 (a, t) -> { a[0] += mapper.applyAsDouble(t); },
       
   470                 (a, b) -> { a[0] += b[0]; return a; },
       
   471                 a -> a[0], CH_NOID);
       
   472     }
       
   473 
       
   474     /**
       
   475      * Returns a {@code Collector} that produces the arithmetic mean of an integer-valued
       
   476      * function applied to the input elements.  If no elements are present,
       
   477      * the result is 0.
       
   478      *
       
   479      * @param <T> the type of the input elements
       
   480      * @param mapper a function extracting the property to be summed
       
   481      * @return a {@code Collector} that produces the sum of a derived property
       
   482      */
       
   483     public static <T> Collector<T, ?, Double>
       
   484     averagingInt(ToIntFunction<? super T> mapper) {
       
   485         return new CollectorImpl<T, long[], Double>(
       
   486                 () -> new long[2],
       
   487                 (a, t) -> { a[0] += mapper.applyAsInt(t); a[1]++; },
       
   488                 (a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; },
       
   489                 a -> (a[1] == 0) ? 0.0d : (double) a[0] / a[1], CH_NOID);
       
   490     }
       
   491 
       
   492     /**
       
   493      * Returns a {@code Collector} that produces the arithmetic mean of a long-valued
       
   494      * function applied to the input elements.  If no elements are present,
       
   495      * the result is 0.
       
   496      *
       
   497      * @param <T> the type of the input elements
       
   498      * @param mapper a function extracting the property to be summed
       
   499      * @return a {@code Collector} that produces the sum of a derived property
       
   500      */
       
   501     public static <T> Collector<T, ?, Double>
       
   502     averagingLong(ToLongFunction<? super T> mapper) {
       
   503         return new CollectorImpl<T, long[], Double>(
       
   504                 () -> new long[2],
       
   505                 (a, t) -> { a[0] += mapper.applyAsLong(t); a[1]++; },
       
   506                 (a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; },
       
   507                 a -> (a[1] == 0) ? 0.0d : (double) a[0] / a[1], CH_NOID);
       
   508     }
       
   509 
       
   510     /**
       
   511      * Returns a {@code Collector} that produces the arithmetic mean of a double-valued
       
   512      * function applied to the input elements.  If no elements are present,
       
   513      * the result is 0.
       
   514      *
       
   515      * <p>The average returned can vary depending upon the order in which
       
   516      * values are recorded, due to accumulated rounding error in
       
   517      * addition of values of differing magnitudes. Values sorted by increasing
       
   518      * absolute magnitude tend to yield more accurate results.  If any recorded
       
   519      * value is a {@code NaN} or the sum is at any point a {@code NaN} then the
       
   520      * average will be {@code NaN}.
       
   521      *
       
   522      * @param <T> the type of the input elements
       
   523      * @param mapper a function extracting the property to be summed
       
   524      * @return a {@code Collector} that produces the sum of a derived property
       
   525      */
       
   526     public static <T> Collector<T, ?, Double>
       
   527     averagingDouble(ToDoubleFunction<? super T> mapper) {
       
   528         return new CollectorImpl<T, double[], Double>(
       
   529                 () -> new double[2],
       
   530                 (a, t) -> { a[0] += mapper.applyAsDouble(t); a[1]++; },
       
   531                 (a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; },
       
   532                 a -> (a[1] == 0) ? 0.0d : a[0] / a[1], CH_NOID);
       
   533     }
       
   534 
       
   535     /**
       
   536      * Returns a {@code Collector} which performs a reduction of its
       
   537      * input elements under a specified {@code BinaryOperator} using the
       
   538      * provided identity.
       
   539      *
       
   540      * @apiNote
       
   541      * The {@code reducing()} collectors are most useful when used in a
       
   542      * multi-level reduction, downstream of {@code groupingBy} or
       
   543      * {@code partitioningBy}.  To perform a simple reduction on a stream,
       
   544      * use {@link Stream#reduce(Object, BinaryOperator)}} instead.
       
   545      *
       
   546      * @param <T> element type for the input and output of the reduction
       
   547      * @param identity the identity value for the reduction (also, the value
       
   548      *                 that is returned when there are no input elements)
       
   549      * @param op a {@code BinaryOperator<T>} used to reduce the input elements
       
   550      * @return a {@code Collector} which implements the reduction operation
       
   551      *
       
   552      * @see #reducing(BinaryOperator)
       
   553      * @see #reducing(Object, Function, BinaryOperator)
       
   554      */
       
   555     public static <T> Collector<T, ?, T>
       
   556     reducing(T identity, BinaryOperator<T> op) {
       
   557         return new CollectorImpl<>(
       
   558                 boxSupplier(identity),
       
   559                 (a, t) -> { a[0] = op.apply(a[0], t); },
       
   560                 (a, b) -> { a[0] = op.apply(a[0], b[0]); return a; },
       
   561                 a -> a[0],
       
   562                 CH_NOID);
       
   563     }
       
   564 
       
   565     @SuppressWarnings("unchecked")
       
   566     private static <T> Supplier<T[]> boxSupplier(T identity) {
       
   567         return () -> (T[]) new Object[] { identity };
       
   568     }
       
   569 
       
   570     /**
       
   571      * Returns a {@code Collector} which performs a reduction of its
       
   572      * input elements under a specified {@code BinaryOperator}.  The result
       
   573      * is described as an {@code Optional<T>}.
   459      *
   574      *
   460      * @apiNote
   575      * @apiNote
   461      * The {@code reducing()} collectors are most useful when used in a
   576      * The {@code reducing()} collectors are most useful when used in a
   462      * multi-level reduction, downstream of {@code groupingBy} or
   577      * multi-level reduction, downstream of {@code groupingBy} or
   463      * {@code partitioningBy}.  To perform a simple reduction on a stream,
   578      * {@code partitioningBy}.  To perform a simple reduction on a stream,
   464      * use {@link Stream#reduce(BinaryOperator)} instead.
   579      * use {@link Stream#reduce(BinaryOperator)} instead.
   465      *
   580      *
   466      * @param <T> element type for the input and output of the reduction
       
   467      * @param identity the identity value for the reduction (also, the value
       
   468      *                 that is returned when there are no input elements)
       
   469      * @param op a {@code BinaryOperator<T>} used to reduce the input elements
       
   470      * @return a {@code Collector} which implements the reduction operation
       
   471      *
       
   472      * @see #reducing(BinaryOperator)
       
   473      * @see #reducing(Object, Function, BinaryOperator)
       
   474      */
       
   475     public static <T> Collector<T, T>
       
   476     reducing(T identity, BinaryOperator<T> op) {
       
   477         return new CollectorImpl<>(() -> identity, (r, t) -> (r == null ? t : op.apply(r, t)), op);
       
   478     }
       
   479 
       
   480     /**
       
   481      * Returns a {@code Collector<T,T>} which performs a reduction of its
       
   482      * input elements under a specified {@code BinaryOperator}.
       
   483      *
       
   484      * @apiNote
       
   485      * The {@code reducing()} collectors are most useful when used in a
       
   486      * multi-level reduction, downstream of {@code groupingBy} or
       
   487      * {@code partitioningBy}.  To perform a simple reduction on a stream,
       
   488      * use {@link Stream#reduce(BinaryOperator)} instead.
       
   489      *
       
   490      * <p>For example, given a stream of {@code Person}, to calculate tallest
   581      * <p>For example, given a stream of {@code Person}, to calculate tallest
   491      * person in each city:
   582      * person in each city:
   492      * <pre>{@code
   583      * <pre>{@code
   493      *     Comparator<Person> byHeight = Comparator.comparing(Person::getHeight);
   584      *     Comparator<Person> byHeight = Comparator.comparing(Person::getHeight);
   494      *     BinaryOperator<Person> tallerOf = BinaryOperator.greaterOf(byHeight);
       
   495      *     Map<City, Person> tallestByCity
   585      *     Map<City, Person> tallestByCity
   496      *         = people.stream().collect(groupingBy(Person::getCity, reducing(tallerOf)));
   586      *         = people.stream().collect(groupingBy(Person::getCity, reducing(BinaryOperator.maxBy(byHeight))));
   497      * }</pre>
       
   498      *
       
   499      * @implSpec
       
   500      * The default implementation is equivalent to:
       
   501      * <pre>{@code
       
   502      *     reducing(null, op);
       
   503      * }</pre>
   587      * }</pre>
   504      *
   588      *
   505      * @param <T> element type for the input and output of the reduction
   589      * @param <T> element type for the input and output of the reduction
   506      * @param op a {@code BinaryOperator<T>} used to reduce the input elements
   590      * @param op a {@code BinaryOperator<T>} used to reduce the input elements
   507      * @return a {@code Collector} which implements the reduction operation
   591      * @return a {@code Collector} which implements the reduction operation
   508      *
   592      *
   509      * @see #reducing(Object, BinaryOperator)
   593      * @see #reducing(Object, BinaryOperator)
   510      * @see #reducing(Object, Function, BinaryOperator)
   594      * @see #reducing(Object, Function, BinaryOperator)
   511      */
   595      */
   512     public static <T> Collector<T, T>
   596     public static <T> Collector<T, ?, Optional<T>>
   513     reducing(BinaryOperator<T> op) {
   597     reducing(BinaryOperator<T> op) {
   514         return reducing(null, op);
   598         class OptionalBox implements Consumer<T> {
   515     }
   599             T value = null;
   516 
   600             boolean present = false;
   517     /**
   601 
   518      * Returns a {@code Collector<T,U>} which performs a reduction of its
   602             @Override
       
   603             public void accept(T t) {
       
   604                 if (present) {
       
   605                     value = op.apply(value, t);
       
   606                 }
       
   607                 else {
       
   608                     value = t;
       
   609                     present = true;
       
   610                 }
       
   611             }
       
   612         }
       
   613 
       
   614         return new CollectorImpl<T, OptionalBox, Optional<T>>(
       
   615                 OptionalBox::new, OptionalBox::accept,
       
   616                 (a, b) -> { if (b.present) a.accept(b.value); return a; },
       
   617                 a -> Optional.ofNullable(a.value), CH_NOID);
       
   618     }
       
   619 
       
   620     /**
       
   621      * Returns a {@code Collector} which performs a reduction of its
   519      * input elements under a specified mapping function and
   622      * input elements under a specified mapping function and
   520      * {@code BinaryOperator}. This is a generalization of
   623      * {@code BinaryOperator}. This is a generalization of
   521      * {@link #reducing(Object, BinaryOperator)} which allows a transformation
   624      * {@link #reducing(Object, BinaryOperator)} which allows a transformation
   522      * of the elements before reduction.
   625      * of the elements before reduction.
   523      *
   626      *
   524      * @apiNote
   627      * @apiNote
   525      * The {@code reducing()} collectors are most useful when used in a
   628      * The {@code reducing()} collectors are most useful when used in a
   526      * multi-level reduction, downstream of {@code groupingBy} or
   629      * multi-level reduction, downstream of {@code groupingBy} or
   527      * {@code partitioningBy}.  To perform a simple reduction on a stream,
   630      * {@code partitioningBy}.  To perform a simple map-reduce on a stream,
   528      * use {@link Stream#reduce(BinaryOperator)} instead.
   631      * use {@link Stream#map(Function)} and {@link Stream#reduce(Object, BinaryOperator)}
       
   632      * instead.
   529      *
   633      *
   530      * <p>For example, given a stream of {@code Person}, to calculate the longest
   634      * <p>For example, given a stream of {@code Person}, to calculate the longest
   531      * last name of residents in each city:
   635      * last name of residents in each city:
   532      * <pre>{@code
   636      * <pre>{@code
   533      *     Comparator<String> byLength = Comparator.comparing(String::length);
   637      *     Comparator<String> byLength = Comparator.comparing(String::length);
   534      *     BinaryOperator<String> longerOf = BinaryOperator.greaterOf(byLength);
       
   535      *     Map<City, String> longestLastNameByCity
   638      *     Map<City, String> longestLastNameByCity
   536      *         = people.stream().collect(groupingBy(Person::getCity,
   639      *         = people.stream().collect(groupingBy(Person::getCity,
   537      *                                              reducing(Person::getLastName, longerOf)));
   640      *                                              reducing(Person::getLastName, BinaryOperator.maxBy(byLength))));
   538      * }</pre>
   641      * }</pre>
   539      *
   642      *
   540      * @param <T> the type of the input elements
   643      * @param <T> the type of the input elements
   541      * @param <U> the type of the mapped values
   644      * @param <U> the type of the mapped values
   542      * @param identity the identity value for the reduction (also, the value
   645      * @param identity the identity value for the reduction (also, the value
   547      *
   650      *
   548      * @see #reducing(Object, BinaryOperator)
   651      * @see #reducing(Object, BinaryOperator)
   549      * @see #reducing(BinaryOperator)
   652      * @see #reducing(BinaryOperator)
   550      */
   653      */
   551     public static <T, U>
   654     public static <T, U>
   552     Collector<T, U> reducing(U identity,
   655     Collector<T, ?, U> reducing(U identity,
   553                              Function<? super T, ? extends U> mapper,
   656                                 Function<? super T, ? extends U> mapper,
   554                              BinaryOperator<U> op) {
   657                                 BinaryOperator<U> op) {
   555         return new CollectorImpl<>(() -> identity,
   658         return new CollectorImpl<>(
   556                                    (r, t) -> (r == null ? mapper.apply(t) : op.apply(r, mapper.apply(t))),
   659                 boxSupplier(identity),
   557                                    op);
   660                 (a, t) -> { a[0] = op.apply(a[0], mapper.apply(t)); },
       
   661                 (a, b) -> { a[0] = op.apply(a[0], b[0]); return a; },
       
   662                 a -> a[0], CH_NOID);
   558     }
   663     }
   559 
   664 
   560     /**
   665     /**
   561      * Returns a {@code Collector} implementing a "group by" operation on
   666      * Returns a {@code Collector} implementing a "group by" operation on
   562      * input elements of type {@code T}, grouping elements according to a
   667      * input elements of type {@code T}, grouping elements according to a
   563      * classification function.
   668      * classification function, and returning the results in a {@code Map}.
   564      *
   669      *
   565      * <p>The classification function maps elements to some key type {@code K}.
   670      * <p>The classification function maps elements to some key type {@code K}.
   566      * The collector produces a {@code Map<K, List<T>>} whose keys are the
   671      * The collector produces a {@code Map<K, List<T>>} whose keys are the
   567      * values resulting from applying the classification function to the input
   672      * values resulting from applying the classification function to the input
   568      * elements, and whose corresponding values are {@code List}s containing the
   673      * elements, and whose corresponding values are {@code List}s containing the
   584      *
   689      *
   585      * @see #groupingBy(Function, Collector)
   690      * @see #groupingBy(Function, Collector)
   586      * @see #groupingBy(Function, Supplier, Collector)
   691      * @see #groupingBy(Function, Supplier, Collector)
   587      * @see #groupingByConcurrent(Function)
   692      * @see #groupingByConcurrent(Function)
   588      */
   693      */
   589     public static <T, K>
   694     public static <T, K> Collector<T, ?, Map<K, List<T>>>
   590     Collector<T, Map<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier) {
   695     groupingBy(Function<? super T, ? extends K> classifier) {
   591         return groupingBy(classifier, HashMap::new, toList());
   696         return groupingBy(classifier, toList());
   592     }
   697     }
   593 
   698 
   594     /**
   699     /**
   595      * Returns a {@code Collector} implementing a cascaded "group by" operation
   700      * Returns a {@code Collector} implementing a cascaded "group by" operation
   596      * on input elements of type {@code T}, grouping elements according to a
   701      * on input elements of type {@code T}, grouping elements according to a
   613      *                                              mapping(Person::getLastName, toSet())));
   718      *                                              mapping(Person::getLastName, toSet())));
   614      * }</pre>
   719      * }</pre>
   615      *
   720      *
   616      * @param <T> the type of the input elements
   721      * @param <T> the type of the input elements
   617      * @param <K> the type of the keys
   722      * @param <K> the type of the keys
       
   723      * @param <A> the intermediate accumulation type of the downstream collector
   618      * @param <D> the result type of the downstream reduction
   724      * @param <D> the result type of the downstream reduction
   619      * @param classifier a classifier function mapping input elements to keys
   725      * @param classifier a classifier function mapping input elements to keys
   620      * @param downstream a {@code Collector} implementing the downstream reduction
   726      * @param downstream a {@code Collector} implementing the downstream reduction
   621      * @return a {@code Collector} implementing the cascaded group-by operation
   727      * @return a {@code Collector} implementing the cascaded group-by operation
   622      * @see #groupingBy(Function)
   728      * @see #groupingBy(Function)
   623      *
   729      *
   624      * @see #groupingBy(Function, Supplier, Collector)
   730      * @see #groupingBy(Function, Supplier, Collector)
   625      * @see #groupingByConcurrent(Function, Collector)
   731      * @see #groupingByConcurrent(Function, Collector)
   626      */
   732      */
   627     public static <T, K, D>
   733     public static <T, K, A, D>
   628     Collector<T, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,
   734     Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,
   629                                        Collector<? super T, D> downstream) {
   735                                           Collector<? super T, A, D> downstream) {
   630         return groupingBy(classifier, HashMap::new, downstream);
   736         return groupingBy(classifier, HashMap::new, downstream);
   631     }
   737     }
   632 
   738 
   633     /**
   739     /**
   634      * Returns a {@code Collector} implementing a cascaded "group by" operation
   740      * Returns a {@code Collector} implementing a cascaded "group by" operation
   651      *                                              mapping(Person::getLastName, toSet())));
   757      *                                              mapping(Person::getLastName, toSet())));
   652      * }</pre>
   758      * }</pre>
   653      *
   759      *
   654      * @param <T> the type of the input elements
   760      * @param <T> the type of the input elements
   655      * @param <K> the type of the keys
   761      * @param <K> the type of the keys
       
   762      * @param <A> the intermediate accumulation type of the downstream collector
   656      * @param <D> the result type of the downstream reduction
   763      * @param <D> the result type of the downstream reduction
   657      * @param <M> the type of the resulting {@code Map}
   764      * @param <M> the type of the resulting {@code Map}
   658      * @param classifier a classifier function mapping input elements to keys
   765      * @param classifier a classifier function mapping input elements to keys
   659      * @param downstream a {@code Collector} implementing the downstream reduction
   766      * @param downstream a {@code Collector} implementing the downstream reduction
   660      * @param mapFactory a function which, when called, produces a new empty
   767      * @param mapFactory a function which, when called, produces a new empty
   663      *
   770      *
   664      * @see #groupingBy(Function, Collector)
   771      * @see #groupingBy(Function, Collector)
   665      * @see #groupingBy(Function)
   772      * @see #groupingBy(Function)
   666      * @see #groupingByConcurrent(Function, Supplier, Collector)
   773      * @see #groupingByConcurrent(Function, Supplier, Collector)
   667      */
   774      */
   668     public static <T, K, D, M extends Map<K, D>>
   775     public static <T, K, D, A, M extends Map<K, D>>
   669     Collector<T, M> groupingBy(Function<? super T, ? extends K> classifier,
   776     Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier,
   670                                Supplier<M> mapFactory,
   777                                   Supplier<M> mapFactory,
   671                                Collector<? super T, D> downstream) {
   778                                   Collector<? super T, A, D> downstream) {
   672         Supplier<D> downstreamSupplier = downstream.resultSupplier();
   779         Supplier<A> downstreamSupplier = downstream.supplier();
   673         BiFunction<D, ? super T, D> downstreamAccumulator = downstream.accumulator();
   780         BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
   674         BiFunction<M, T, M> accumulator = (m, t) -> {
   781         BiConsumer<Map<K, A>, T> accumulator = (m, t) -> {
   675             K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
   782             K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
   676             D oldContainer = m.computeIfAbsent(key, k -> downstreamSupplier.get());
   783             A container = m.computeIfAbsent(key, k -> downstreamSupplier.get());
   677             D newContainer = downstreamAccumulator.apply(oldContainer, t);
   784             downstreamAccumulator.accept(container, t);
   678             if (newContainer != oldContainer)
       
   679                 m.put(key, newContainer);
       
   680             return m;
       
   681         };
   785         };
   682         return new CollectorImpl<>(mapFactory, accumulator, mapMerger(downstream.combiner()), CH_STRICT);
   786         BinaryOperator<Map<K, A>> merger = Collectors.<K, A, Map<K, A>>mapMerger(downstream.combiner());
   683     }
   787         @SuppressWarnings("unchecked")
   684 
   788         Supplier<Map<K, A>> mangledFactory = (Supplier<Map<K, A>>) mapFactory;
   685     /**
   789 
   686      * Returns a {@code Collector} implementing a concurrent "group by"
   790         if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
       
   791             return new CollectorImpl<>(mangledFactory, accumulator, merger, CH_ID);
       
   792         }
       
   793         else {
       
   794             @SuppressWarnings("unchecked")
       
   795             Function<A, A> downstreamFinisher = (Function<A, A>) downstream.finisher();
       
   796             Function<Map<K, A>, M> finisher = intermediate -> {
       
   797                 intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v));
       
   798                 @SuppressWarnings("unchecked")
       
   799                 M castResult = (M) intermediate;
       
   800                 return castResult;
       
   801             };
       
   802             return new CollectorImpl<>(mangledFactory, accumulator, merger, finisher, CH_NOID);
       
   803         }
       
   804     }
       
   805 
       
   806     /**
       
   807      * Returns a concurrent {@code Collector} implementing a "group by"
   687      * operation on input elements of type {@code T}, grouping elements
   808      * operation on input elements of type {@code T}, grouping elements
   688      * according to a classification function.
   809      * according to a classification function.
   689      *
   810      *
   690      * <p>This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
   811      * <p>This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
   691      * {@link Collector.Characteristics#UNORDERED unordered} Collector.
   812      * {@link Collector.Characteristics#UNORDERED unordered} Collector.
   714      * @see #groupingBy(Function)
   835      * @see #groupingBy(Function)
   715      * @see #groupingByConcurrent(Function, Collector)
   836      * @see #groupingByConcurrent(Function, Collector)
   716      * @see #groupingByConcurrent(Function, Supplier, Collector)
   837      * @see #groupingByConcurrent(Function, Supplier, Collector)
   717      */
   838      */
   718     public static <T, K>
   839     public static <T, K>
   719     Collector<T, ConcurrentMap<K, List<T>>> groupingByConcurrent(Function<? super T, ? extends K> classifier) {
   840     Collector<T, ?, ConcurrentMap<K, List<T>>>
       
   841     groupingByConcurrent(Function<? super T, ? extends K> classifier) {
   720         return groupingByConcurrent(classifier, ConcurrentHashMap::new, toList());
   842         return groupingByConcurrent(classifier, ConcurrentHashMap::new, toList());
   721     }
   843     }
   722 
   844 
   723     /**
   845     /**
   724      * Returns a {@code Collector} implementing a concurrent cascaded "group by"
   846      * Returns a concurrent {@code Collector} implementing a cascaded "group by"
   725      * operation on input elements of type {@code T}, grouping elements
   847      * operation on input elements of type {@code T}, grouping elements
   726      * according to a classification function, and then performing a reduction
   848      * according to a classification function, and then performing a reduction
   727      * operation on the values associated with a given key using the specified
   849      * operation on the values associated with a given key using the specified
   728      * downstream {@code Collector}.
   850      * downstream {@code Collector}.
   729      *
   851      *
   737      *
   859      *
   738      * <p>For example, to compute the set of last names of people in each city,
   860      * <p>For example, to compute the set of last names of people in each city,
   739      * where the city names are sorted:
   861      * where the city names are sorted:
   740      * <pre>{@code
   862      * <pre>{@code
   741      *     ConcurrentMap<City, Set<String>> namesByCity
   863      *     ConcurrentMap<City, Set<String>> namesByCity
   742      *         = people.stream().collect(groupingByConcurrent(Person::getCity, TreeMap::new,
   864      *         = people.stream().collect(groupingByConcurrent(Person::getCity, ConcurrentSkipListMap::new,
   743      *                                                        mapping(Person::getLastName, toSet())));
   865      *                                                        mapping(Person::getLastName, toSet())));
   744      * }</pre>
   866      * }</pre>
   745      *
   867      *
   746      * @param <T> the type of the input elements
   868      * @param <T> the type of the input elements
   747      * @param <K> the type of the keys
   869      * @param <K> the type of the keys
       
   870      * @param <A> the intermediate accumulation type of the downstream collector
   748      * @param <D> the result type of the downstream reduction
   871      * @param <D> the result type of the downstream reduction
   749      * @param classifier a classifier function mapping input elements to keys
   872      * @param classifier a classifier function mapping input elements to keys
   750      * @param downstream a {@code Collector} implementing the downstream reduction
   873      * @param downstream a {@code Collector} implementing the downstream reduction
   751      * @return a {@code Collector} implementing the cascaded group-by operation
   874      * @return a {@code Collector} implementing the cascaded group-by operation
   752      *
   875      *
   753      * @see #groupingBy(Function, Collector)
   876      * @see #groupingBy(Function, Collector)
   754      * @see #groupingByConcurrent(Function)
   877      * @see #groupingByConcurrent(Function)
   755      * @see #groupingByConcurrent(Function, Supplier, Collector)
   878      * @see #groupingByConcurrent(Function, Supplier, Collector)
   756      */
   879      */
   757     public static <T, K, D>
   880     public static <T, K, A, D>
   758     Collector<T, ConcurrentMap<K, D>> groupingByConcurrent(Function<? super T, ? extends K> classifier,
   881     Collector<T, ?, ConcurrentMap<K, D>> groupingByConcurrent(Function<? super T, ? extends K> classifier,
   759                                                            Collector<? super T, D> downstream) {
   882                                                               Collector<? super T, A, D> downstream) {
   760         return groupingByConcurrent(classifier, ConcurrentHashMap::new, downstream);
   883         return groupingByConcurrent(classifier, ConcurrentHashMap::new, downstream);
   761     }
   884     }
   762 
   885 
   763     /**
   886     /**
   764      * Returns a concurrent {@code Collector} implementing a cascaded "group by"
   887      * Returns a concurrent {@code Collector} implementing a cascaded "group by"
   785      * }</pre>
   908      * }</pre>
   786      *
   909      *
   787      *
   910      *
   788      * @param <T> the type of the input elements
   911      * @param <T> the type of the input elements
   789      * @param <K> the type of the keys
   912      * @param <K> the type of the keys
       
   913      * @param <A> the intermediate accumulation type of the downstream collector
   790      * @param <D> the result type of the downstream reduction
   914      * @param <D> the result type of the downstream reduction
   791      * @param <M> the type of the resulting {@code ConcurrentMap}
   915      * @param <M> the type of the resulting {@code ConcurrentMap}
   792      * @param classifier a classifier function mapping input elements to keys
   916      * @param classifier a classifier function mapping input elements to keys
   793      * @param downstream a {@code Collector} implementing the downstream reduction
   917      * @param downstream a {@code Collector} implementing the downstream reduction
   794      * @param mapFactory a function which, when called, produces a new empty
   918      * @param mapFactory a function which, when called, produces a new empty
   797      *
   921      *
   798      * @see #groupingByConcurrent(Function)
   922      * @see #groupingByConcurrent(Function)
   799      * @see #groupingByConcurrent(Function, Collector)
   923      * @see #groupingByConcurrent(Function, Collector)
   800      * @see #groupingBy(Function, Supplier, Collector)
   924      * @see #groupingBy(Function, Supplier, Collector)
   801      */
   925      */
   802     public static <T, K, D, M extends ConcurrentMap<K, D>>
   926     public static <T, K, A, D, M extends ConcurrentMap<K, D>>
   803     Collector<T, M> groupingByConcurrent(Function<? super T, ? extends K> classifier,
   927     Collector<T, ?, M> groupingByConcurrent(Function<? super T, ? extends K> classifier,
   804                                          Supplier<M> mapFactory,
   928                                             Supplier<M> mapFactory,
   805                                          Collector<? super T, D> downstream) {
   929                                             Collector<? super T, A, D> downstream) {
   806         Supplier<D> downstreamSupplier = downstream.resultSupplier();
   930         Supplier<A> downstreamSupplier = downstream.supplier();
   807         BiFunction<D, ? super T, D> downstreamAccumulator = downstream.accumulator();
   931         BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
   808         BinaryOperator<M> combiner = mapMerger(downstream.combiner());
   932         BinaryOperator<ConcurrentMap<K, A>> merger = Collectors.<K, A, ConcurrentMap<K, A>>mapMerger(downstream.combiner());
       
   933         @SuppressWarnings("unchecked")
       
   934         Supplier<ConcurrentMap<K, A>> mangledFactory = (Supplier<ConcurrentMap<K, A>>) mapFactory;
       
   935         BiConsumer<ConcurrentMap<K, A>, T> accumulator;
   809         if (downstream.characteristics().contains(Collector.Characteristics.CONCURRENT)) {
   936         if (downstream.characteristics().contains(Collector.Characteristics.CONCURRENT)) {
   810             BiFunction<M, T, M> accumulator = (m, t) -> {
   937             accumulator = (m, t) -> {
   811                 K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
   938                 K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
   812                 downstreamAccumulator.apply(m.computeIfAbsent(key, k -> downstreamSupplier.get()), t);
   939                 A resultContainer = m.computeIfAbsent(key, k -> downstreamSupplier.get());
   813                 return m;
   940                 downstreamAccumulator.accept(resultContainer, t);
   814             };
   941             };
   815             return new CollectorImpl<>(mapFactory, accumulator, combiner, CH_CONCURRENT);
   942         }
   816         } else if (downstream.characteristics().contains(Collector.Characteristics.STRICTLY_MUTATIVE)) {
   943         else {
   817             BiFunction<M, T, M> accumulator = (m, t) -> {
   944             accumulator = (m, t) -> {
   818                 K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
   945                 K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
   819                 D resultContainer = m.computeIfAbsent(key, k -> downstreamSupplier.get());
   946                 A resultContainer = m.computeIfAbsent(key, k -> downstreamSupplier.get());
   820                 synchronized (resultContainer) {
   947                 synchronized (resultContainer) {
   821                     downstreamAccumulator.apply(resultContainer, t);
   948                     downstreamAccumulator.accept(resultContainer, t);
   822                 }
   949                 }
   823                 return m;
       
   824             };
   950             };
   825             return new CollectorImpl<>(mapFactory, accumulator, combiner, CH_CONCURRENT);
   951         }
   826         } else {
   952 
   827             BiFunction<M, T, M> accumulator = (m, t) -> {
   953         if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
   828                 K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
   954             return new CollectorImpl<>(mangledFactory, accumulator, merger, CH_CONCURRENT_ID);
   829                 do {
   955         }
   830                     D oldResult = m.computeIfAbsent(key, k -> downstreamSupplier.get());
   956         else {
   831                     if (oldResult == null) {
   957             @SuppressWarnings("unchecked")
   832                         if (m.putIfAbsent(key, downstreamAccumulator.apply(null, t)) == null)
   958             Function<A, A> downstreamFinisher = (Function<A, A>) downstream.finisher();
   833                             return m;
   959             Function<ConcurrentMap<K, A>, M> finisher = intermediate -> {
   834                     } else {
   960                 intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v));
   835                         synchronized (oldResult) {
   961                 @SuppressWarnings("unchecked")
   836                             if (m.get(key) != oldResult)
   962                 M castResult = (M) intermediate;
   837                                 continue;
   963                 return castResult;
   838                             D newResult = downstreamAccumulator.apply(oldResult, t);
       
   839                             if (oldResult != newResult)
       
   840                                 m.put(key, newResult);
       
   841                             return m;
       
   842                         }
       
   843                     }
       
   844                 } while (true);
       
   845             };
   964             };
   846             return new CollectorImpl<>(mapFactory, accumulator, combiner, CH_CONCURRENT);
   965             return new CollectorImpl<>(mangledFactory, accumulator, merger, finisher, CH_CONCURRENT_NOID);
   847         }
   966         }
   848     }
   967     }
   849 
   968 
   850     /**
   969     /**
   851      * Returns a {@code Collector} which partitions the input elements according
   970      * Returns a {@code Collector} which partitions the input elements according
   860      * @return a {@code Collector} implementing the partitioning operation
   979      * @return a {@code Collector} implementing the partitioning operation
   861      *
   980      *
   862      * @see #partitioningBy(Predicate, Collector)
   981      * @see #partitioningBy(Predicate, Collector)
   863      */
   982      */
   864     public static <T>
   983     public static <T>
   865     Collector<T, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate) {
   984     Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate) {
   866         return partitioningBy(predicate, toList());
   985         return partitioningBy(predicate, toList());
   867     }
   986     }
   868 
   987 
   869     /**
   988     /**
   870      * Returns a {@code Collector} which partitions the input elements according
   989      * Returns a {@code Collector} which partitions the input elements according
   875      *
   994      *
   876      * <p>There are no guarantees on the type, mutability,
   995      * <p>There are no guarantees on the type, mutability,
   877      * serializability, or thread-safety of the {@code Map} returned.
   996      * serializability, or thread-safety of the {@code Map} returned.
   878      *
   997      *
   879      * @param <T> the type of the input elements
   998      * @param <T> the type of the input elements
       
   999      * @param <A> the intermediate accumulation type of the downstream collector
   880      * @param <D> the result type of the downstream reduction
  1000      * @param <D> the result type of the downstream reduction
   881      * @param predicate a predicate used for classifying input elements
  1001      * @param predicate a predicate used for classifying input elements
   882      * @param downstream a {@code Collector} implementing the downstream
  1002      * @param downstream a {@code Collector} implementing the downstream
   883      *                   reduction
  1003      *                   reduction
   884      * @return a {@code Collector} implementing the cascaded partitioning
  1004      * @return a {@code Collector} implementing the cascaded partitioning
   885      *         operation
  1005      *         operation
   886      *
  1006      *
   887      * @see #partitioningBy(Predicate)
  1007      * @see #partitioningBy(Predicate)
   888      */
  1008      */
   889     public static <T, D>
  1009     public static <T, D, A>
   890     Collector<T, Map<Boolean, D>> partitioningBy(Predicate<? super T> predicate,
  1010     Collector<T, ?, Map<Boolean, D>> partitioningBy(Predicate<? super T> predicate,
   891                                                  Collector<? super T, D> downstream) {
  1011                                                     Collector<? super T, A, D> downstream) {
   892         BiFunction<D, ? super T, D> downstreamAccumulator = downstream.accumulator();
  1012         @SuppressWarnings("unchecked")
   893         BiFunction<Map<Boolean, D>, T, Map<Boolean, D>> accumulator = (result, t) -> {
  1013         BiConsumer<D, ? super T> downstreamAccumulator = (BiConsumer<D, ? super T>) downstream.accumulator();
       
  1014         BiConsumer<Map<Boolean, A>, T> accumulator = (result, t) -> {
   894             Partition<D> asPartition = ((Partition<D>) result);
  1015             Partition<D> asPartition = ((Partition<D>) result);
   895             if (predicate.test(t)) {
  1016             downstreamAccumulator.accept(predicate.test(t) ? asPartition.forTrue : asPartition.forFalse, t);
   896                 D newResult = downstreamAccumulator.apply(asPartition.forTrue, t);
       
   897                 if (newResult != asPartition.forTrue)
       
   898                     asPartition.forTrue = newResult;
       
   899             } else {
       
   900                 D newResult = downstreamAccumulator.apply(asPartition.forFalse, t);
       
   901                 if (newResult != asPartition.forFalse)
       
   902                     asPartition.forFalse = newResult;
       
   903             }
       
   904             return result;
       
   905         };
  1017         };
   906         return new CollectorImpl<>(() -> new Partition<>(downstream.resultSupplier().get(),
  1018         BinaryOperator<A> op = downstream.combiner();
   907                                                          downstream.resultSupplier().get()),
  1019         BinaryOperator<Map<Boolean, A>> merger = (m1, m2) -> {
   908                                    accumulator, partitionMerger(downstream.combiner()), CH_STRICT);
  1020             Partition<A> left = (Partition<A>) m1;
   909     }
  1021             Partition<A> right = (Partition<A>) m2;
   910 
  1022             return new Partition<>(op.apply(left.forTrue, right.forTrue),
   911     /**
  1023                                    op.apply(left.forFalse, right.forFalse));
   912      * Merge function for two partitions, given a merge function for the
       
   913      * elements.
       
   914      */
       
   915     private static <D> BinaryOperator<Map<Boolean, D>> partitionMerger(BinaryOperator<D> op) {
       
   916         return (m1, m2) -> {
       
   917             Partition<D> left = (Partition<D>) m1;
       
   918             Partition<D> right = (Partition<D>) m2;
       
   919             if (left.forFalse == null)
       
   920                 left.forFalse = right.forFalse;
       
   921             else if (right.forFalse != null)
       
   922                 left.forFalse = op.apply(left.forFalse, right.forFalse);
       
   923             if (left.forTrue == null)
       
   924                 left.forTrue = right.forTrue;
       
   925             else if (right.forTrue != null)
       
   926                 left.forTrue = op.apply(left.forTrue, right.forTrue);
       
   927             return left;
       
   928         };
  1024         };
   929     }
  1025         Supplier<Map<Boolean, A>> supplier = () -> new Partition<>(downstream.supplier().get(),
   930 
  1026                                                                    downstream.supplier().get());
   931     /**
  1027         if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
   932      * Accumulate elements into a {@code Map} whose keys and values are the
  1028             return new CollectorImpl<>(supplier, accumulator, merger, CH_ID);
   933      * result of applying mapping functions to the input elements.
  1029         }
   934      * If the mapped keys contains duplicates (according to
  1030         else {
       
  1031             Function<Map<Boolean, A>, Map<Boolean, D>> finisher = (Map<Boolean, A> par) -> {
       
  1032                 Partition<A> asAPartition = (Partition<A>) par;
       
  1033                 return new Partition<>(downstream.finisher().apply(asAPartition.forTrue),
       
  1034                                        downstream.finisher().apply(asAPartition.forFalse));
       
  1035             };
       
  1036             return new CollectorImpl<>(supplier, accumulator, merger, finisher, CH_NOID);
       
  1037         }
       
  1038     }
       
  1039 
       
  1040     /**
       
  1041      * Returns a {@code Collector} that accumulate elements into a
       
  1042      * {@code Map} whose keys and values are the result of applying the provided
       
  1043      * mapping functions to the input elements.
       
  1044      *
       
  1045      * <p>If the mapped keys contains duplicates (according to
   935      * {@link Object#equals(Object)}), an {@code IllegalStateException} is
  1046      * {@link Object#equals(Object)}), an {@code IllegalStateException} is
   936      * thrown when the collection operation is performed.  If the mapped keys
  1047      * thrown when the collection operation is performed.  If the mapped keys
   937      * may have duplicates, use {@link #toMap(Function, Function, BinaryOperator)}
  1048      * may have duplicates, use {@link #toMap(Function, Function, BinaryOperator)}
   938      * instead.
  1049      * instead.
   939      *
  1050      *
   968      * @see #toMap(Function, Function, BinaryOperator)
  1079      * @see #toMap(Function, Function, BinaryOperator)
   969      * @see #toMap(Function, Function, BinaryOperator, Supplier)
  1080      * @see #toMap(Function, Function, BinaryOperator, Supplier)
   970      * @see #toConcurrentMap(Function, Function)
  1081      * @see #toConcurrentMap(Function, Function)
   971      */
  1082      */
   972     public static <T, K, U>
  1083     public static <T, K, U>
   973     Collector<T, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
  1084     Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
   974                                  Function<? super T, ? extends U> valueMapper) {
  1085                                     Function<? super T, ? extends U> valueMapper) {
   975         return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
  1086         return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
   976     }
  1087     }
   977 
  1088 
   978     /**
  1089     /**
   979      * Accumulate elements into a {@code Map} whose keys and values are the
  1090      * Returns a {@code Collector} that accumulate elements into a
   980      * result of applying mapping functions to the input elements. If the mapped
  1091      * {@code Map} whose keys and values are the result of applying the provided
       
  1092      * mapping functions to the input elements.
       
  1093      *
       
  1094      * <p>If the mapped
   981      * keys contains duplicates (according to {@link Object#equals(Object)}),
  1095      * keys contains duplicates (according to {@link Object#equals(Object)}),
   982      * the value mapping function is applied to each equal element, and the
  1096      * the value mapping function is applied to each equal element, and the
   983      * results are merged using the provided merging function.
  1097      * results are merged using the provided merging function.
   984      *
  1098      *
   985      * @apiNote
  1099      * @apiNote
   986      * There are multiple ways to deal with collisions between multiple elements
  1100      * There are multiple ways to deal with collisions between multiple elements
   987      * mapping to the same key.  There are some predefined merging functions,
  1101      * mapping to the same key.  The other forms of {@code toMap} simply use
   988      * such as {@link #throwingMerger()}, {@link #firstWinsMerger()}, and
  1102      * a merge function that throws unconditionally, but you can easily write
   989      * {@link #lastWinsMerger()}, that implement common policies, or you can
  1103      * more flexible merge policies.  For example, if you have a stream
   990      * implement custom policies easily.  For example, if you have a stream
       
   991      * of {@code Person}, and you want to produce a "phone book" mapping name to
  1104      * of {@code Person}, and you want to produce a "phone book" mapping name to
   992      * address, but it is possible that two persons have the same name, you can
  1105      * address, but it is possible that two persons have the same name, you can
   993      * do as follows to gracefully deals with these collisions, and produce a
  1106      * do as follows to gracefully deals with these collisions, and produce a
   994      * {@code Map} mapping names to a concatenated list of addresses:
  1107      * {@code Map} mapping names to a concatenated list of addresses:
   995      * <pre>{@code
  1108      * <pre>{@code
  1016      * @see #toMap(Function, Function)
  1129      * @see #toMap(Function, Function)
  1017      * @see #toMap(Function, Function, BinaryOperator, Supplier)
  1130      * @see #toMap(Function, Function, BinaryOperator, Supplier)
  1018      * @see #toConcurrentMap(Function, Function, BinaryOperator)
  1131      * @see #toConcurrentMap(Function, Function, BinaryOperator)
  1019      */
  1132      */
  1020     public static <T, K, U>
  1133     public static <T, K, U>
  1021     Collector<T, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
  1134     Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
  1022                                  Function<? super T, ? extends U> valueMapper,
  1135                                     Function<? super T, ? extends U> valueMapper,
  1023                                  BinaryOperator<U> mergeFunction) {
  1136                                     BinaryOperator<U> mergeFunction) {
  1024         return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
  1137         return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
  1025     }
  1138     }
  1026 
  1139 
  1027     /**
  1140     /**
  1028      * Accumulate elements into a {@code Map} whose keys and values are the
  1141      * Returns a {@code Collector} that accumulate elements into a
  1029      * result of applying mapping functions to the input elements. If the mapped
  1142      * {@code Map} whose keys and values are the result of applying the provided
       
  1143      * mapping functions to the input elements.
       
  1144      *
       
  1145      * <p>If the mapped
  1030      * keys contains duplicates (according to {@link Object#equals(Object)}),
  1146      * keys contains duplicates (according to {@link Object#equals(Object)}),
  1031      * the value mapping function is applied to each equal element, and the
  1147      * the value mapping function is applied to each equal element, and the
  1032      * results are merged using the provided merging function.  The {@code Map}
  1148      * results are merged using the provided merging function.  The {@code Map}
  1033      * is created by a provided supplier function.
  1149      * is created by a provided supplier function.
  1034      *
  1150      *
  1052      * @see #toMap(Function, Function)
  1168      * @see #toMap(Function, Function)
  1053      * @see #toMap(Function, Function, BinaryOperator)
  1169      * @see #toMap(Function, Function, BinaryOperator)
  1054      * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
  1170      * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
  1055      */
  1171      */
  1056     public static <T, K, U, M extends Map<K, U>>
  1172     public static <T, K, U, M extends Map<K, U>>
  1057     Collector<T, M> toMap(Function<? super T, ? extends K> keyMapper,
  1173     Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
  1058                           Function<? super T, ? extends U> valueMapper,
  1174                                 Function<? super T, ? extends U> valueMapper,
  1059                           BinaryOperator<U> mergeFunction,
  1175                                 BinaryOperator<U> mergeFunction,
  1060                           Supplier<M> mapSupplier) {
  1176                                 Supplier<M> mapSupplier) {
  1061         BiFunction<M, T, M> accumulator
  1177         BiConsumer<M, T> accumulator
  1062                 = (map, element) -> {
  1178                 = (map, element) -> map.merge(keyMapper.apply(element),
  1063                       map.merge(keyMapper.apply(element), valueMapper.apply(element), mergeFunction);
  1179                                               valueMapper.apply(element), mergeFunction);
  1064                       return map;
  1180         return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
  1065                   };
  1181     }
  1066         return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_STRICT);
  1182 
  1067     }
  1183     /**
  1068 
  1184      * Returns a {@code Collector} that accumulate elements into a
  1069     /**
  1185      * {@code ConcurrentMap} whose keys and values are the result of applying
  1070      * Accumulate elements into a {@code ConcurrentMap} whose keys and values
  1186      * the provided mapping functions to the input elements.
  1071      * are the result of applying mapping functions to the input elements.
  1187      *
  1072      * If the mapped keys contains duplicates (according to
  1188      * <p>If the mapped keys contains duplicates (according to
  1073      * {@link Object#equals(Object)}), an {@code IllegalStateException} is
  1189      * {@link Object#equals(Object)}), an {@code IllegalStateException} is
  1074      * thrown when the collection operation is performed.  If the mapped keys
  1190      * thrown when the collection operation is performed.  If the mapped keys
  1075      * may have duplicates, use
  1191      * may have duplicates, use
  1076      * {@link #toConcurrentMap(Function, Function, BinaryOperator)} instead.
  1192      * {@link #toConcurrentMap(Function, Function, BinaryOperator)} instead.
  1077      *
  1193      *
  1110      * @see #toMap(Function, Function)
  1226      * @see #toMap(Function, Function)
  1111      * @see #toConcurrentMap(Function, Function, BinaryOperator)
  1227      * @see #toConcurrentMap(Function, Function, BinaryOperator)
  1112      * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
  1228      * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
  1113      */
  1229      */
  1114     public static <T, K, U>
  1230     public static <T, K, U>
  1115     Collector<T, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
  1231     Collector<T, ?, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
  1116                                                      Function<? super T, ? extends U> valueMapper) {
  1232                                                         Function<? super T, ? extends U> valueMapper) {
  1117         return toConcurrentMap(keyMapper, valueMapper, throwingMerger(), ConcurrentHashMap::new);
  1233         return toConcurrentMap(keyMapper, valueMapper, throwingMerger(), ConcurrentHashMap::new);
  1118     }
  1234     }
  1119 
  1235 
  1120     /**
  1236     /**
  1121      * Accumulate elements into a {@code ConcurrentMap} whose keys and values
  1237      * Returns a {@code Collector} that accumulate elements into a
  1122      * are the result of applying mapping functions to the input elements. If
  1238      * {@code ConcurrentMap} whose keys and values are the result of applying
  1123      * the mapped keys contains duplicates (according to {@link Object#equals(Object)}),
  1239      * the provided mapping functions to the input elements.
       
  1240      *
       
  1241      * <p>If the mapped keys contains duplicates (according to {@link Object#equals(Object)}),
  1124      * the value mapping function is applied to each equal element, and the
  1242      * the value mapping function is applied to each equal element, and the
  1125      * results are merged using the provided merging function.
  1243      * results are merged using the provided merging function.
  1126      *
  1244      *
  1127      * @apiNote
  1245      * @apiNote
  1128      * There are multiple ways to deal with collisions between multiple elements
  1246      * There are multiple ways to deal with collisions between multiple elements
  1129      * mapping to the same key.  There are some predefined merging functions,
  1247      * mapping to the same key.  The other forms of {@code toConcurrentMap} simply use
  1130      * such as {@link #throwingMerger()}, {@link #firstWinsMerger()}, and
  1248      * a merge function that throws unconditionally, but you can easily write
  1131      * {@link #lastWinsMerger()}, that implement common policies, or you can
  1249      * more flexible merge policies.  For example, if you have a stream
  1132      * implement custom policies easily.  For example, if you have a stream
       
  1133      * of {@code Person}, and you want to produce a "phone book" mapping name to
  1250      * of {@code Person}, and you want to produce a "phone book" mapping name to
  1134      * address, but it is possible that two persons have the same name, you can
  1251      * address, but it is possible that two persons have the same name, you can
  1135      * do as follows to gracefully deals with these collisions, and produce a
  1252      * do as follows to gracefully deals with these collisions, and produce a
  1136      * {@code Map} mapping names to a concatenated list of addresses:
  1253      * {@code Map} mapping names to a concatenated list of addresses:
  1137      * <pre>{@code
  1254      * <pre>{@code
  1161      * @see #toConcurrentMap(Function, Function)
  1278      * @see #toConcurrentMap(Function, Function)
  1162      * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
  1279      * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
  1163      * @see #toMap(Function, Function, BinaryOperator)
  1280      * @see #toMap(Function, Function, BinaryOperator)
  1164      */
  1281      */
  1165     public static <T, K, U>
  1282     public static <T, K, U>
  1166     Collector<T, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
  1283     Collector<T, ?, ConcurrentMap<K,U>>
  1167                                                      Function<? super T, ? extends U> valueMapper,
  1284     toConcurrentMap(Function<? super T, ? extends K> keyMapper,
  1168                                                      BinaryOperator<U> mergeFunction) {
  1285                     Function<? super T, ? extends U> valueMapper,
       
  1286                     BinaryOperator<U> mergeFunction) {
  1169         return toConcurrentMap(keyMapper, valueMapper, mergeFunction, ConcurrentHashMap::new);
  1287         return toConcurrentMap(keyMapper, valueMapper, mergeFunction, ConcurrentHashMap::new);
  1170     }
  1288     }
  1171 
  1289 
  1172     /**
  1290     /**
  1173      * Accumulate elements into a {@code ConcurrentMap} whose keys and values
  1291      * Returns a {@code Collector} that accumulate elements into a
  1174      * are the result of applying mapping functions to the input elements. If
  1292      * {@code ConcurrentMap} whose keys and values are the result of applying
  1175      * the mapped keys contains duplicates (according to {@link Object#equals(Object)}),
  1293      * the provided mapping functions to the input elements.
       
  1294      *
       
  1295      * <p>If the mapped keys contains duplicates (according to {@link Object#equals(Object)}),
  1176      * the value mapping function is applied to each equal element, and the
  1296      * the value mapping function is applied to each equal element, and the
  1177      * results are merged using the provided merging function.  The
  1297      * results are merged using the provided merging function.  The
  1178      * {@code ConcurrentMap} is created by a provided supplier function.
  1298      * {@code ConcurrentMap} is created by a provided supplier function.
  1179      *
  1299      *
  1180      * <p>This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
  1300      * <p>This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
  1200      * @see #toConcurrentMap(Function, Function)
  1320      * @see #toConcurrentMap(Function, Function)
  1201      * @see #toConcurrentMap(Function, Function, BinaryOperator)
  1321      * @see #toConcurrentMap(Function, Function, BinaryOperator)
  1202      * @see #toMap(Function, Function, BinaryOperator, Supplier)
  1322      * @see #toMap(Function, Function, BinaryOperator, Supplier)
  1203      */
  1323      */
  1204     public static <T, K, U, M extends ConcurrentMap<K, U>>
  1324     public static <T, K, U, M extends ConcurrentMap<K, U>>
  1205     Collector<T, M> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
  1325     Collector<T, ?, M> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
  1206                                     Function<? super T, ? extends U> valueMapper,
  1326                                        Function<? super T, ? extends U> valueMapper,
  1207                                     BinaryOperator<U> mergeFunction,
  1327                                        BinaryOperator<U> mergeFunction,
  1208                                     Supplier<M> mapSupplier) {
  1328                                        Supplier<M> mapSupplier) {
  1209         BiFunction<M, T, M> accumulator = (map, element) -> {
  1329         BiConsumer<M, T> accumulator
  1210             map.merge(keyMapper.apply(element), valueMapper.apply(element), mergeFunction);
  1330                 = (map, element) -> map.merge(keyMapper.apply(element),
  1211             return map;
  1331                                               valueMapper.apply(element), mergeFunction);
  1212         };
  1332         return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_CONCURRENT_ID);
  1213         return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_CONCURRENT);
       
  1214     }
  1333     }
  1215 
  1334 
  1216     /**
  1335     /**
  1217      * Returns a {@code Collector} which applies an {@code int}-producing
  1336      * Returns a {@code Collector} which applies an {@code int}-producing
  1218      * mapping function to each input element, and returns summary statistics
  1337      * mapping function to each input element, and returns summary statistics
  1220      *
  1339      *
  1221      * @param <T> the type of the input elements
  1340      * @param <T> the type of the input elements
  1222      * @param mapper a mapping function to apply to each element
  1341      * @param mapper a mapping function to apply to each element
  1223      * @return a {@code Collector} implementing the summary-statistics reduction
  1342      * @return a {@code Collector} implementing the summary-statistics reduction
  1224      *
  1343      *
  1225      * @see #toDoubleSummaryStatistics(ToDoubleFunction)
  1344      * @see #summarizingDouble(ToDoubleFunction)
  1226      * @see #toLongSummaryStatistics(ToLongFunction)
  1345      * @see #summarizingLong(ToLongFunction)
  1227      */
  1346      */
  1228     public static <T>
  1347     public static <T>
  1229     Collector<T, IntSummaryStatistics> toIntSummaryStatistics(ToIntFunction<? super T> mapper) {
  1348     Collector<T, ?, IntSummaryStatistics> summarizingInt(ToIntFunction<? super T> mapper) {
  1230         return new CollectorImpl<>(IntSummaryStatistics::new,
  1349         return new CollectorImpl<T, IntSummaryStatistics, IntSummaryStatistics>(
  1231                                    (r, t) -> { r.accept(mapper.applyAsInt(t)); return r; },
  1350                 IntSummaryStatistics::new,
  1232                                    (l, r) -> { l.combine(r); return l; }, CH_STRICT);
  1351                 (r, t) -> r.accept(mapper.applyAsInt(t)),
       
  1352                 (l, r) -> { l.combine(r); return l; }, CH_ID);
  1233     }
  1353     }
  1234 
  1354 
  1235     /**
  1355     /**
  1236      * Returns a {@code Collector} which applies an {@code long}-producing
  1356      * Returns a {@code Collector} which applies an {@code long}-producing
  1237      * mapping function to each input element, and returns summary statistics
  1357      * mapping function to each input element, and returns summary statistics
  1239      *
  1359      *
  1240      * @param <T> the type of the input elements
  1360      * @param <T> the type of the input elements
  1241      * @param mapper the mapping function to apply to each element
  1361      * @param mapper the mapping function to apply to each element
  1242      * @return a {@code Collector} implementing the summary-statistics reduction
  1362      * @return a {@code Collector} implementing the summary-statistics reduction
  1243      *
  1363      *
  1244      * @see #toDoubleSummaryStatistics(ToDoubleFunction)
  1364      * @see #summarizingDouble(ToDoubleFunction)
  1245      * @see #toIntSummaryStatistics(ToIntFunction)
  1365      * @see #summarizingInt(ToIntFunction)
  1246      */
  1366      */
  1247     public static <T>
  1367     public static <T>
  1248     Collector<T, LongSummaryStatistics> toLongSummaryStatistics(ToLongFunction<? super T> mapper) {
  1368     Collector<T, ?, LongSummaryStatistics> summarizingLong(ToLongFunction<? super T> mapper) {
  1249         return new CollectorImpl<>(LongSummaryStatistics::new,
  1369         return new CollectorImpl<T, LongSummaryStatistics, LongSummaryStatistics>(
  1250                                    (r, t) -> { r.accept(mapper.applyAsLong(t)); return r; },
  1370                 LongSummaryStatistics::new,
  1251                                    (l, r) -> { l.combine(r); return l; }, CH_STRICT);
  1371                 (r, t) -> r.accept(mapper.applyAsLong(t)),
       
  1372                 (l, r) -> { l.combine(r); return l; }, CH_ID);
  1252     }
  1373     }
  1253 
  1374 
  1254     /**
  1375     /**
  1255      * Returns a {@code Collector} which applies an {@code double}-producing
  1376      * Returns a {@code Collector} which applies an {@code double}-producing
  1256      * mapping function to each input element, and returns summary statistics
  1377      * mapping function to each input element, and returns summary statistics
  1258      *
  1379      *
  1259      * @param <T> the type of the input elements
  1380      * @param <T> the type of the input elements
  1260      * @param mapper a mapping function to apply to each element
  1381      * @param mapper a mapping function to apply to each element
  1261      * @return a {@code Collector} implementing the summary-statistics reduction
  1382      * @return a {@code Collector} implementing the summary-statistics reduction
  1262      *
  1383      *
  1263      * @see #toLongSummaryStatistics(ToLongFunction)
  1384      * @see #summarizingLong(ToLongFunction)
  1264      * @see #toIntSummaryStatistics(ToIntFunction)
  1385      * @see #summarizingInt(ToIntFunction)
  1265      */
  1386      */
  1266     public static <T>
  1387     public static <T>
  1267     Collector<T, DoubleSummaryStatistics> toDoubleSummaryStatistics(ToDoubleFunction<? super T> mapper) {
  1388     Collector<T, ?, DoubleSummaryStatistics> summarizingDouble(ToDoubleFunction<? super T> mapper) {
  1268         return new CollectorImpl<>(DoubleSummaryStatistics::new,
  1389         return new CollectorImpl<T, DoubleSummaryStatistics, DoubleSummaryStatistics>(
  1269                                    (r, t) -> { r.accept(mapper.applyAsDouble(t)); return r; },
  1390                 DoubleSummaryStatistics::new,
  1270                                    (l, r) -> { l.combine(r); return l; }, CH_STRICT);
  1391                 (r, t) -> r.accept(mapper.applyAsDouble(t)),
       
  1392                 (l, r) -> { l.combine(r); return l; }, CH_ID);
  1271     }
  1393     }
  1272 
  1394 
  1273     /**
  1395     /**
  1274      * Implementation class used by partitioningBy.
  1396      * Implementation class used by partitioningBy.
  1275      */
  1397      */
  1276     private static final class Partition<T>
  1398     private static final class Partition<T>
  1277             extends AbstractMap<Boolean, T>
  1399             extends AbstractMap<Boolean, T>
  1278             implements Map<Boolean, T> {
  1400             implements Map<Boolean, T> {
  1279         T forTrue;
  1401         final T forTrue;
  1280         T forFalse;
  1402         final T forFalse;
  1281 
  1403 
  1282         Partition(T forTrue, T forFalse) {
  1404         Partition(T forTrue, T forFalse) {
  1283             this.forTrue = forTrue;
  1405             this.forTrue = forTrue;
  1284             this.forFalse = forFalse;
  1406             this.forFalse = forFalse;
  1285         }
  1407         }
  1287         @Override
  1409         @Override
  1288         public Set<Map.Entry<Boolean, T>> entrySet() {
  1410         public Set<Map.Entry<Boolean, T>> entrySet() {
  1289             return new AbstractSet<Map.Entry<Boolean, T>>() {
  1411             return new AbstractSet<Map.Entry<Boolean, T>>() {
  1290                 @Override
  1412                 @Override
  1291                 public Iterator<Map.Entry<Boolean, T>> iterator() {
  1413                 public Iterator<Map.Entry<Boolean, T>> iterator() {
  1292 
  1414                     Map.Entry<Boolean, T> falseEntry = new SimpleImmutableEntry<>(false, forFalse);
  1293                     return new Iterator<Map.Entry<Boolean, T>>() {
  1415                     Map.Entry<Boolean, T> trueEntry = new SimpleImmutableEntry<>(true, forTrue);
  1294                         int state = 0;
  1416                     return Arrays.asList(falseEntry, trueEntry).iterator();
  1295 
       
  1296                         @Override
       
  1297                         public boolean hasNext() {
       
  1298                             return state < 2;
       
  1299                         }
       
  1300 
       
  1301                         @Override
       
  1302                         public Map.Entry<Boolean, T> next() {
       
  1303                             if (state >= 2)
       
  1304                                 throw new NoSuchElementException();
       
  1305                             return (state++ == 0)
       
  1306                                    ? new SimpleImmutableEntry<>(false, forFalse)
       
  1307                                    : new SimpleImmutableEntry<>(true, forTrue);
       
  1308                         }
       
  1309                     };
       
  1310                 }
  1417                 }
  1311 
  1418 
  1312                 @Override
  1419                 @Override
  1313                 public int size() {
  1420                 public int size() {
  1314                     return 2;
  1421                     return 2;