< prev index next >

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

Print this page
rev 53968 : enable Collector pre-sizing
rev 53969 : added map loadfactor and collector nullchecks


  28 import java.util.AbstractSet;
  29 import java.util.ArrayList;
  30 import java.util.Collection;
  31 import java.util.Collections;
  32 import java.util.Comparator;
  33 import java.util.DoubleSummaryStatistics;
  34 import java.util.EnumSet;
  35 import java.util.HashMap;
  36 import java.util.HashSet;
  37 import java.util.IntSummaryStatistics;
  38 import java.util.Iterator;
  39 import java.util.List;
  40 import java.util.LongSummaryStatistics;
  41 import java.util.Map;
  42 import java.util.Objects;
  43 import java.util.Optional;
  44 import java.util.Set;
  45 import java.util.StringJoiner;
  46 import java.util.concurrent.ConcurrentHashMap;
  47 import java.util.concurrent.ConcurrentMap;
  48 import java.util.function.BiConsumer;
  49 import java.util.function.BiFunction;
  50 import java.util.function.BinaryOperator;
  51 import java.util.function.Consumer;
  52 import java.util.function.Function;
  53 import java.util.function.Predicate;
  54 import java.util.function.Supplier;
  55 import java.util.function.ToDoubleFunction;
  56 import java.util.function.ToIntFunction;
  57 import java.util.function.ToLongFunction;
  58 
  59 /**
  60  * Implementations of {@link Collector} that implement various useful reduction
  61  * operations, such as accumulating elements into collections, summarizing
  62  * elements according to various criteria, etc.
  63  *
  64  * <p>The following are examples of using the predefined collectors to perform
  65  * common mutable reduction tasks:
  66  *
  67  * <pre>{@code
  68  * // Accumulate names into a List
  69  * List<String> list = people.stream()
  70  *   .map(Person::getName)
  71  *   .collect(Collectors.toList());
  72  *
  73  * // Accumulate names into a TreeSet
  74  * Set<String> set = people.stream()
  75  *   .map(Person::getName)
  76  *   .collect(Collectors.toCollection(TreeSet::new));
  77  *


 176         return (map, element) -> {
 177             K k = keyMapper.apply(element);
 178             V v = Objects.requireNonNull(valueMapper.apply(element));
 179             V u = map.putIfAbsent(k, v);
 180             if (u != null) throw duplicateKeyException(k, u, v);
 181         };
 182     }
 183 
 184     @SuppressWarnings("unchecked")
 185     private static <I, R> Function<I, R> castingIdentity() {
 186         return i -> (R) i;
 187     }
 188 
 189     /**
 190      * Simple implementation class for {@code Collector}.
 191      *
 192      * @param <T> the type of elements to be collected
 193      * @param <R> the type of the result
 194      */
 195     static class CollectorImpl<T, A, R> implements Collector<T, A, R> {

 196         private final Supplier<A> supplier;
 197         private final BiConsumer<A, T> accumulator;
 198         private final BinaryOperator<A> combiner;
 199         private final Function<A, R> finisher;
 200         private final Set<Characteristics> characteristics;
 201 
 202         CollectorImpl(Supplier<A> supplier,

 203                       BiConsumer<A, T> accumulator,
 204                       BinaryOperator<A> combiner,
 205                       Function<A,R> finisher,
 206                       Set<Characteristics> characteristics) {

 207             this.supplier = supplier;
 208             this.accumulator = accumulator;
 209             this.combiner = combiner;
 210             this.finisher = finisher;
 211             this.characteristics = characteristics;
 212         }
 213 
















 214         CollectorImpl(Supplier<A> supplier,
 215                       BiConsumer<A, T> accumulator,
 216                       BinaryOperator<A> combiner,
 217                       Set<Characteristics> characteristics) {
 218             this(supplier, accumulator, combiner, castingIdentity(), characteristics);
 219         }
 220 
 221         @Override
 222         public BiConsumer<A, T> accumulator() {
 223             return accumulator;
 224         }
 225 
 226         @Override
 227         public Supplier<A> supplier() {
 228             return supplier;
 229         }
 230 
 231         @Override





 232         public BinaryOperator<A> combiner() {
 233             return combiner;
 234         }
 235 
 236         @Override
 237         public Function<A, R> finisher() {
 238             return finisher;
 239         }
 240 
 241         @Override
 242         public Set<Characteristics> characteristics() {
 243             return characteristics;
 244         }
 245     }
 246 
 247     /**
 248      * Returns a {@code Collector} that accumulates the input elements into a
 249      * new {@code Collection}, in encounter order.  The {@code Collection} is
 250      * created by the provided factory.
 251      *


 258      */
 259     public static <T, C extends Collection<T>>
 260     Collector<T, ?, C> toCollection(Supplier<C> collectionFactory) {
 261         return new CollectorImpl<>(collectionFactory, Collection<T>::add,
 262                                    (r1, r2) -> { r1.addAll(r2); return r1; },
 263                                    CH_ID);
 264     }
 265 
 266     /**
 267      * Returns a {@code Collector} that accumulates the input elements into a
 268      * new {@code List}. There are no guarantees on the type, mutability,
 269      * serializability, or thread-safety of the {@code List} returned; if more
 270      * control over the returned {@code List} is required, use {@link #toCollection(Supplier)}.
 271      *
 272      * @param <T> the type of the input elements
 273      * @return a {@code Collector} which collects all the input elements into a
 274      * {@code List}, in encounter order
 275      */
 276     public static <T>
 277     Collector<T, ?, List<T>> toList() {
 278         return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,


 279                                    (left, right) -> { left.addAll(right); return left; },
 280                                    CH_ID);
 281     }
 282 
 283     /**
 284      * Returns a {@code Collector} that accumulates the input elements into an
 285      * <a href="../List.html#unmodifiable">unmodifiable List</a> in encounter
 286      * order. The returned Collector disallows null values and will throw
 287      * {@code NullPointerException} if it is presented with a null value.
 288      *
 289      * @param <T> the type of the input elements
 290      * @return a {@code Collector} that accumulates the input elements into an
 291      * <a href="../List.html#unmodifiable">unmodifiable List</a> in encounter order
 292      * @since 10
 293      */
 294     @SuppressWarnings("unchecked")
 295     public static <T>
 296     Collector<T, ?, List<T>> toUnmodifiableList() {
 297         return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,


 298                                    (left, right) -> { left.addAll(right); return left; },
 299                                    list -> (List<T>)List.of(list.toArray()),
 300                                    CH_NOID);
 301     }
 302 
 303     /**
 304      * Returns a {@code Collector} that accumulates the input elements into a
 305      * new {@code Set}. There are no guarantees on the type, mutability,
 306      * serializability, or thread-safety of the {@code Set} returned; if more
 307      * control over the returned {@code Set} is required, use
 308      * {@link #toCollection(Supplier)}.
 309      *
 310      * <p>This is an {@link Collector.Characteristics#UNORDERED unordered}
 311      * Collector.
 312      *
 313      * @param <T> the type of the input elements
 314      * @return a {@code Collector} which collects all the input elements into a
 315      * {@code Set}
 316      */
 317     public static <T>


 440      * Map<City, Set<String>> lastNamesByCity
 441      *   = people.stream().collect(
 442      *     groupingBy(Person::getCity,
 443      *                mapping(Person::getLastName,
 444      *                        toSet())));
 445      * }</pre>
 446      *
 447      * @param <T> the type of the input elements
 448      * @param <U> type of elements accepted by downstream collector
 449      * @param <A> intermediate accumulation type of the downstream collector
 450      * @param <R> result type of collector
 451      * @param mapper a function to be applied to the input elements
 452      * @param downstream a collector which will accept mapped values
 453      * @return a collector which applies the mapping function to the input
 454      * elements and provides the mapped results to the downstream collector
 455      */
 456     public static <T, U, A, R>
 457     Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper,
 458                                Collector<? super U, A, R> downstream) {
 459         BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
 460         return new CollectorImpl<>(downstream.supplier(),
 461                                    (r, t) -> downstreamAccumulator.accept(r, mapper.apply(t)),
 462                                    downstream.combiner(), downstream.finisher(),
 463                                    downstream.characteristics());
 464     }
 465 
 466     /**
 467      * Adapts a {@code Collector} accepting elements of type {@code U} to one
 468      * accepting elements of type {@code T} by applying a flat mapping function
 469      * to each input element before accumulation.  The flat mapping function
 470      * maps an input element to a {@link Stream stream} covering zero or more
 471      * output elements that are then accumulated downstream.  Each mapped stream
 472      * is {@link java.util.stream.BaseStream#close() closed} after its contents
 473      * have been placed downstream.  (If a mapped stream is {@code null}
 474      * an empty stream is used, instead.)
 475      *
 476      * @apiNote
 477      * The {@code flatMapping()} collectors are most useful when used in a
 478      * multi-level reduction, such as downstream of a {@code groupingBy} or
 479      * {@code partitioningBy}.  For example, given a stream of
 480      * {@code Order}, to accumulate the set of line items for each customer:


 576      * @param <A> intermediate accumulation type of the downstream collector
 577      * @param <R> result type of the downstream collector
 578      * @param <RR> result type of the resulting collector
 579      * @param downstream a collector
 580      * @param finisher a function to be applied to the final result of the downstream collector
 581      * @return a collector which performs the action of the downstream collector,
 582      * followed by an additional finishing step
 583      */
 584     public static<T,A,R,RR> Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream,
 585                                                                 Function<R,RR> finisher) {
 586         Set<Collector.Characteristics> characteristics = downstream.characteristics();
 587         if (characteristics.contains(Collector.Characteristics.IDENTITY_FINISH)) {
 588             if (characteristics.size() == 1)
 589                 characteristics = Collectors.CH_NOID;
 590             else {
 591                 characteristics = EnumSet.copyOf(characteristics);
 592                 characteristics.remove(Collector.Characteristics.IDENTITY_FINISH);
 593                 characteristics = Collections.unmodifiableSet(characteristics);
 594             }
 595         }
 596         return new CollectorImpl<>(downstream.supplier(),

 597                                    downstream.accumulator(),
 598                                    downstream.combiner(),
 599                                    downstream.finisher().andThen(finisher),
 600                                    characteristics);
 601     }
 602 
 603     /**
 604      * Returns a {@code Collector} accepting elements of type {@code T} that
 605      * counts the number of input elements.  If no elements are present, the
 606      * result is 0.
 607      *
 608      * @implSpec
 609      * This produces a result equivalent to:
 610      * <pre>{@code
 611      *     reducing(0L, e -> 1L, Long::sum)
 612      * }</pre>
 613      *
 614      * @param <T> the type of the input elements
 615      * @return a {@code Collector} that counts the input elements
 616      */


1439      * not required that results are inserted into the {@code Map} in encounter
1440      * order, using {@link #toConcurrentMap(Function, Function)}
1441      * may offer better parallel performance.
1442      *
1443      * @param <T> the type of the input elements
1444      * @param <K> the output type of the key mapping function
1445      * @param <U> the output type of the value mapping function
1446      * @param keyMapper a mapping function to produce keys
1447      * @param valueMapper a mapping function to produce values
1448      * @return a {@code Collector} which collects elements into a {@code Map}
1449      * whose keys and values are the result of applying mapping functions to
1450      * the input elements
1451      *
1452      * @see #toMap(Function, Function, BinaryOperator)
1453      * @see #toMap(Function, Function, BinaryOperator, Supplier)
1454      * @see #toConcurrentMap(Function, Function)
1455      */
1456     public static <T, K, U>
1457     Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
1458                                     Function<? super T, ? extends U> valueMapper) {
1459         return new CollectorImpl<>(HashMap::new,

1460                                    uniqKeysMapAccumulator(keyMapper, valueMapper),
1461                                    uniqKeysMapMerger(),
1462                                    CH_ID);
1463     }
1464 
1465     /**
1466      * Returns a {@code Collector} that accumulates the input elements into an
1467      * <a href="../Map.html#unmodifiable">unmodifiable Map</a>,
1468      * whose keys and values are the result of applying the provided
1469      * mapping functions to the input elements.
1470      *
1471      * <p>If the mapped keys contain duplicates (according to
1472      * {@link Object#equals(Object)}), an {@code IllegalStateException} is
1473      * thrown when the collection operation is performed.  If the mapped keys
1474      * might have duplicates, use {@link #toUnmodifiableMap(Function, Function, BinaryOperator)}
1475      * to handle merging of the values.
1476      *
1477      * <p>The returned Collector disallows null keys and values. If either mapping function
1478      * returns null, {@code NullPointerException} will be thrown.
1479      *


1698      * <p>This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
1699      * {@link Collector.Characteristics#UNORDERED unordered} Collector.
1700      *
1701      * @param <T> the type of the input elements
1702      * @param <K> the output type of the key mapping function
1703      * @param <U> the output type of the value mapping function
1704      * @param keyMapper the mapping function to produce keys
1705      * @param valueMapper the mapping function to produce values
1706      * @return a concurrent, unordered {@code Collector} which collects elements into a
1707      * {@code ConcurrentMap} whose keys are the result of applying a key mapping
1708      * function to the input elements, and whose values are the result of
1709      * applying a value mapping function to the input elements
1710      *
1711      * @see #toMap(Function, Function)
1712      * @see #toConcurrentMap(Function, Function, BinaryOperator)
1713      * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
1714      */
1715     public static <T, K, U>
1716     Collector<T, ?, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
1717                                                         Function<? super T, ? extends U> valueMapper) {
1718         return new CollectorImpl<>(ConcurrentHashMap::new,

1719                                    uniqKeysMapAccumulator(keyMapper, valueMapper),
1720                                    uniqKeysMapMerger(),
1721                                    CH_CONCURRENT_ID);
1722     }
1723 
1724     /**
1725      * Returns a concurrent {@code Collector} that accumulates elements into a
1726      * {@code ConcurrentMap} whose keys and values are the result of applying
1727      * the provided mapping functions to the input elements.
1728      *
1729      * <p>If the mapped keys contain duplicates (according to {@link Object#equals(Object)}),
1730      * the value mapping function is applied to each equal element, and the
1731      * results are merged using the provided merging function.
1732      *
1733      * <p>There are no guarantees on the type, mutability, or serializability
1734      * of the {@code ConcurrentMap} returned.
1735      *
1736      * @apiNote
1737      * There are multiple ways to deal with collisions between multiple elements
1738      * mapping to the same key.  The other forms of {@code toConcurrentMap} simply use


1916      * @return a {@code Collector} which aggregates the results of two supplied collectors.
1917      * @since 12
1918      */
1919     public static <T, R1, R2, R>
1920     Collector<T, ?, R> teeing(Collector<? super T, ?, R1> downstream1,
1921                               Collector<? super T, ?, R2> downstream2,
1922                               BiFunction<? super R1, ? super R2, R> merger) {
1923         return teeing0(downstream1, downstream2, merger);
1924     }
1925 
1926     private static <T, A1, A2, R1, R2, R>
1927     Collector<T, ?, R> teeing0(Collector<? super T, A1, R1> downstream1,
1928                                Collector<? super T, A2, R2> downstream2,
1929                                BiFunction<? super R1, ? super R2, R> merger) {
1930         Objects.requireNonNull(downstream1, "downstream1");
1931         Objects.requireNonNull(downstream2, "downstream2");
1932         Objects.requireNonNull(merger, "merger");
1933 
1934         Supplier<A1> c1Supplier = Objects.requireNonNull(downstream1.supplier(), "downstream1 supplier");
1935         Supplier<A2> c2Supplier = Objects.requireNonNull(downstream2.supplier(), "downstream2 supplier");




1936         BiConsumer<A1, ? super T> c1Accumulator =
1937                 Objects.requireNonNull(downstream1.accumulator(), "downstream1 accumulator");
1938         BiConsumer<A2, ? super T> c2Accumulator =
1939                 Objects.requireNonNull(downstream2.accumulator(), "downstream2 accumulator");
1940         BinaryOperator<A1> c1Combiner = Objects.requireNonNull(downstream1.combiner(), "downstream1 combiner");
1941         BinaryOperator<A2> c2Combiner = Objects.requireNonNull(downstream2.combiner(), "downstream2 combiner");
1942         Function<A1, R1> c1Finisher = Objects.requireNonNull(downstream1.finisher(), "downstream1 finisher");
1943         Function<A2, R2> c2Finisher = Objects.requireNonNull(downstream2.finisher(), "downstream2 finisher");
1944 
1945         Set<Collector.Characteristics> characteristics;
1946         Set<Collector.Characteristics> c1Characteristics = downstream1.characteristics();
1947         Set<Collector.Characteristics> c2Characteristics = downstream2.characteristics();
1948         if (CH_ID.containsAll(c1Characteristics) || CH_ID.containsAll(c2Characteristics)) {
1949             characteristics = CH_NOID;
1950         } else {
1951             EnumSet<Collector.Characteristics> c = EnumSet.noneOf(Collector.Characteristics.class);
1952             c.addAll(c1Characteristics);
1953             c.retainAll(c2Characteristics);
1954             c.remove(Collector.Characteristics.IDENTITY_FINISH);
1955             characteristics = Collections.unmodifiableSet(c);
1956         }
1957 
1958         class PairBox {
1959             A1 left = c1Supplier.get();
1960             A2 right = c2Supplier.get();










1961 
1962             void add(T t) {
1963                 c1Accumulator.accept(left, t);
1964                 c2Accumulator.accept(right, t);
1965             }
1966 
1967             PairBox combine(PairBox other) {
1968                 left = c1Combiner.apply(left, other.left);
1969                 right = c2Combiner.apply(right, other.right);
1970                 return this;
1971             }
1972 
1973             R get() {
1974                 R1 r1 = c1Finisher.apply(left);
1975                 R2 r2 = c2Finisher.apply(right);
1976                 return merger.apply(r1, r2);
1977             }
1978         }
1979 
1980         return new CollectorImpl<>(PairBox::new, PairBox::add, PairBox::combine, PairBox::get, characteristics);





1981     }
1982 
1983     /**
1984      * Implementation class used by partitioningBy.
1985      */
1986     private static final class Partition<T>
1987             extends AbstractMap<Boolean, T>
1988             implements Map<Boolean, T> {
1989         final T forTrue;
1990         final T forFalse;
1991 
1992         Partition(T forTrue, T forFalse) {
1993             this.forTrue = forTrue;
1994             this.forFalse = forFalse;
1995         }
1996 
1997         @Override
1998         public Set<Map.Entry<Boolean, T>> entrySet() {
1999             return new AbstractSet<>() {
2000                 @Override


  28 import java.util.AbstractSet;
  29 import java.util.ArrayList;
  30 import java.util.Collection;
  31 import java.util.Collections;
  32 import java.util.Comparator;
  33 import java.util.DoubleSummaryStatistics;
  34 import java.util.EnumSet;
  35 import java.util.HashMap;
  36 import java.util.HashSet;
  37 import java.util.IntSummaryStatistics;
  38 import java.util.Iterator;
  39 import java.util.List;
  40 import java.util.LongSummaryStatistics;
  41 import java.util.Map;
  42 import java.util.Objects;
  43 import java.util.Optional;
  44 import java.util.Set;
  45 import java.util.StringJoiner;
  46 import java.util.concurrent.ConcurrentHashMap;
  47 import java.util.concurrent.ConcurrentMap;
  48 import java.util.function.*;









  49 
  50 /**
  51  * Implementations of {@link Collector} that implement various useful reduction
  52  * operations, such as accumulating elements into collections, summarizing
  53  * elements according to various criteria, etc.
  54  *
  55  * <p>The following are examples of using the predefined collectors to perform
  56  * common mutable reduction tasks:
  57  *
  58  * <pre>{@code
  59  * // Accumulate names into a List
  60  * List<String> list = people.stream()
  61  *   .map(Person::getName)
  62  *   .collect(Collectors.toList());
  63  *
  64  * // Accumulate names into a TreeSet
  65  * Set<String> set = people.stream()
  66  *   .map(Person::getName)
  67  *   .collect(Collectors.toCollection(TreeSet::new));
  68  *


 167         return (map, element) -> {
 168             K k = keyMapper.apply(element);
 169             V v = Objects.requireNonNull(valueMapper.apply(element));
 170             V u = map.putIfAbsent(k, v);
 171             if (u != null) throw duplicateKeyException(k, u, v);
 172         };
 173     }
 174 
 175     @SuppressWarnings("unchecked")
 176     private static <I, R> Function<I, R> castingIdentity() {
 177         return i -> (R) i;
 178     }
 179 
 180     /**
 181      * Simple implementation class for {@code Collector}.
 182      *
 183      * @param <T> the type of elements to be collected
 184      * @param <R> the type of the result
 185      */
 186     static class CollectorImpl<T, A, R> implements Collector<T, A, R> {
 187         private final IntFunction<A> sizedSupplier;
 188         private final Supplier<A> supplier;
 189         private final BiConsumer<A, T> accumulator;
 190         private final BinaryOperator<A> combiner;
 191         private final Function<A, R> finisher;
 192         private final Set<Characteristics> characteristics;
 193 
 194         CollectorImpl(IntFunction<A> sizedSupplier,
 195                       Supplier<A> supplier,
 196                       BiConsumer<A, T> accumulator,
 197                       BinaryOperator<A> combiner,
 198                       Function<A,R> finisher,
 199                       Set<Characteristics> characteristics) {
 200             this.sizedSupplier = sizedSupplier;
 201             this.supplier = supplier;
 202             this.accumulator = accumulator;
 203             this.combiner = combiner;
 204             this.finisher = finisher;
 205             this.characteristics = characteristics;
 206         }
 207 
 208         CollectorImpl(IntFunction<A> sizedSupplier,
 209                       Supplier<A> supplier,
 210                       BiConsumer<A, T> accumulator,
 211                       BinaryOperator<A> combiner,
 212                       Set<Characteristics> characteristics) {
 213             this(sizedSupplier, supplier, accumulator, combiner, castingIdentity(), characteristics);
 214         }
 215 
 216         CollectorImpl(Supplier<A> supplier,
 217                       BiConsumer<A, T> accumulator,
 218                       BinaryOperator<A> combiner,
 219                       Function<A,R> finisher,
 220                       Set<Characteristics> characteristics) {
 221             this(ignored -> supplier.get(), supplier, accumulator, combiner, finisher, characteristics);
 222         }
 223 
 224         CollectorImpl(Supplier<A> supplier,
 225                       BiConsumer<A, T> accumulator,
 226                       BinaryOperator<A> combiner,
 227                       Set<Characteristics> characteristics) {
 228             this(supplier, accumulator, combiner, castingIdentity(), characteristics);
 229         }
 230 
 231         @Override
 232         public BiConsumer<A, T> accumulator() {
 233             return accumulator;
 234         }
 235 
 236         @Override
 237         public Supplier<A> supplier() {
 238             return supplier;
 239         }
 240 
 241         @Override
 242         public IntFunction<A> sizedSupplier() {
 243             return sizedSupplier;
 244         }
 245 
 246         @Override
 247         public BinaryOperator<A> combiner() {
 248             return combiner;
 249         }
 250 
 251         @Override
 252         public Function<A, R> finisher() {
 253             return finisher;
 254         }
 255 
 256         @Override
 257         public Set<Characteristics> characteristics() {
 258             return characteristics;
 259         }
 260     }
 261 
 262     /**
 263      * Returns a {@code Collector} that accumulates the input elements into a
 264      * new {@code Collection}, in encounter order.  The {@code Collection} is
 265      * created by the provided factory.
 266      *


 273      */
 274     public static <T, C extends Collection<T>>
 275     Collector<T, ?, C> toCollection(Supplier<C> collectionFactory) {
 276         return new CollectorImpl<>(collectionFactory, Collection<T>::add,
 277                                    (r1, r2) -> { r1.addAll(r2); return r1; },
 278                                    CH_ID);
 279     }
 280 
 281     /**
 282      * Returns a {@code Collector} that accumulates the input elements into a
 283      * new {@code List}. There are no guarantees on the type, mutability,
 284      * serializability, or thread-safety of the {@code List} returned; if more
 285      * control over the returned {@code List} is required, use {@link #toCollection(Supplier)}.
 286      *
 287      * @param <T> the type of the input elements
 288      * @return a {@code Collector} which collects all the input elements into a
 289      * {@code List}, in encounter order
 290      */
 291     public static <T>
 292     Collector<T, ?, List<T>> toList() {
 293         return new CollectorImpl<>((IntFunction<List<T>>) ArrayList::new,
 294                                    (Supplier<List<T>>) ArrayList::new,
 295                                    List::add,
 296                                    (left, right) -> { left.addAll(right); return left; },
 297                                    CH_ID);
 298     }
 299 
 300     /**
 301      * Returns a {@code Collector} that accumulates the input elements into an
 302      * <a href="../List.html#unmodifiable">unmodifiable List</a> in encounter
 303      * order. The returned Collector disallows null values and will throw
 304      * {@code NullPointerException} if it is presented with a null value.
 305      *
 306      * @param <T> the type of the input elements
 307      * @return a {@code Collector} that accumulates the input elements into an
 308      * <a href="../List.html#unmodifiable">unmodifiable List</a> in encounter order
 309      * @since 10
 310      */
 311     @SuppressWarnings("unchecked")
 312     public static <T>
 313     Collector<T, ?, List<T>> toUnmodifiableList() {
 314         return new CollectorImpl<>((IntFunction<List<T>>) ArrayList::new,
 315                                    (Supplier<List<T>>) ArrayList::new,
 316                                    List::add,
 317                                    (left, right) -> { left.addAll(right); return left; },
 318                                    list -> (List<T>)List.of(list.toArray()),
 319                                    CH_NOID);
 320     }
 321 
 322     /**
 323      * Returns a {@code Collector} that accumulates the input elements into a
 324      * new {@code Set}. There are no guarantees on the type, mutability,
 325      * serializability, or thread-safety of the {@code Set} returned; if more
 326      * control over the returned {@code Set} is required, use
 327      * {@link #toCollection(Supplier)}.
 328      *
 329      * <p>This is an {@link Collector.Characteristics#UNORDERED unordered}
 330      * Collector.
 331      *
 332      * @param <T> the type of the input elements
 333      * @return a {@code Collector} which collects all the input elements into a
 334      * {@code Set}
 335      */
 336     public static <T>


 459      * Map<City, Set<String>> lastNamesByCity
 460      *   = people.stream().collect(
 461      *     groupingBy(Person::getCity,
 462      *                mapping(Person::getLastName,
 463      *                        toSet())));
 464      * }</pre>
 465      *
 466      * @param <T> the type of the input elements
 467      * @param <U> type of elements accepted by downstream collector
 468      * @param <A> intermediate accumulation type of the downstream collector
 469      * @param <R> result type of collector
 470      * @param mapper a function to be applied to the input elements
 471      * @param downstream a collector which will accept mapped values
 472      * @return a collector which applies the mapping function to the input
 473      * elements and provides the mapped results to the downstream collector
 474      */
 475     public static <T, U, A, R>
 476     Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper,
 477                                Collector<? super U, A, R> downstream) {
 478         BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
 479         return new CollectorImpl<>(downstream.sizedSupplier(), downstream.supplier(),
 480                                    (r, t) -> downstreamAccumulator.accept(r, mapper.apply(t)),
 481                                    downstream.combiner(), downstream.finisher(),
 482                                    downstream.characteristics());
 483     }
 484 
 485     /**
 486      * Adapts a {@code Collector} accepting elements of type {@code U} to one
 487      * accepting elements of type {@code T} by applying a flat mapping function
 488      * to each input element before accumulation.  The flat mapping function
 489      * maps an input element to a {@link Stream stream} covering zero or more
 490      * output elements that are then accumulated downstream.  Each mapped stream
 491      * is {@link java.util.stream.BaseStream#close() closed} after its contents
 492      * have been placed downstream.  (If a mapped stream is {@code null}
 493      * an empty stream is used, instead.)
 494      *
 495      * @apiNote
 496      * The {@code flatMapping()} collectors are most useful when used in a
 497      * multi-level reduction, such as downstream of a {@code groupingBy} or
 498      * {@code partitioningBy}.  For example, given a stream of
 499      * {@code Order}, to accumulate the set of line items for each customer:


 595      * @param <A> intermediate accumulation type of the downstream collector
 596      * @param <R> result type of the downstream collector
 597      * @param <RR> result type of the resulting collector
 598      * @param downstream a collector
 599      * @param finisher a function to be applied to the final result of the downstream collector
 600      * @return a collector which performs the action of the downstream collector,
 601      * followed by an additional finishing step
 602      */
 603     public static<T,A,R,RR> Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream,
 604                                                                 Function<R,RR> finisher) {
 605         Set<Collector.Characteristics> characteristics = downstream.characteristics();
 606         if (characteristics.contains(Collector.Characteristics.IDENTITY_FINISH)) {
 607             if (characteristics.size() == 1)
 608                 characteristics = Collectors.CH_NOID;
 609             else {
 610                 characteristics = EnumSet.copyOf(characteristics);
 611                 characteristics.remove(Collector.Characteristics.IDENTITY_FINISH);
 612                 characteristics = Collections.unmodifiableSet(characteristics);
 613             }
 614         }
 615         return new CollectorImpl<>(downstream.sizedSupplier(),
 616                                    downstream.supplier(),
 617                                    downstream.accumulator(),
 618                                    downstream.combiner(),
 619                                    downstream.finisher().andThen(finisher),
 620                                    characteristics);
 621     }
 622 
 623     /**
 624      * Returns a {@code Collector} accepting elements of type {@code T} that
 625      * counts the number of input elements.  If no elements are present, the
 626      * result is 0.
 627      *
 628      * @implSpec
 629      * This produces a result equivalent to:
 630      * <pre>{@code
 631      *     reducing(0L, e -> 1L, Long::sum)
 632      * }</pre>
 633      *
 634      * @param <T> the type of the input elements
 635      * @return a {@code Collector} that counts the input elements
 636      */


1459      * not required that results are inserted into the {@code Map} in encounter
1460      * order, using {@link #toConcurrentMap(Function, Function)}
1461      * may offer better parallel performance.
1462      *
1463      * @param <T> the type of the input elements
1464      * @param <K> the output type of the key mapping function
1465      * @param <U> the output type of the value mapping function
1466      * @param keyMapper a mapping function to produce keys
1467      * @param valueMapper a mapping function to produce values
1468      * @return a {@code Collector} which collects elements into a {@code Map}
1469      * whose keys and values are the result of applying mapping functions to
1470      * the input elements
1471      *
1472      * @see #toMap(Function, Function, BinaryOperator)
1473      * @see #toMap(Function, Function, BinaryOperator, Supplier)
1474      * @see #toConcurrentMap(Function, Function)
1475      */
1476     public static <T, K, U>
1477     Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
1478                                     Function<? super T, ? extends U> valueMapper) {
1479         return new CollectorImpl<>(size -> new HashMap<>((int) Math.ceil(size / .75), .75f),
1480                                    HashMap::new,
1481                                    uniqKeysMapAccumulator(keyMapper, valueMapper),
1482                                    uniqKeysMapMerger(),
1483                                    CH_ID);
1484     }
1485 
1486     /**
1487      * Returns a {@code Collector} that accumulates the input elements into an
1488      * <a href="../Map.html#unmodifiable">unmodifiable Map</a>,
1489      * whose keys and values are the result of applying the provided
1490      * mapping functions to the input elements.
1491      *
1492      * <p>If the mapped keys contain duplicates (according to
1493      * {@link Object#equals(Object)}), an {@code IllegalStateException} is
1494      * thrown when the collection operation is performed.  If the mapped keys
1495      * might have duplicates, use {@link #toUnmodifiableMap(Function, Function, BinaryOperator)}
1496      * to handle merging of the values.
1497      *
1498      * <p>The returned Collector disallows null keys and values. If either mapping function
1499      * returns null, {@code NullPointerException} will be thrown.
1500      *


1719      * <p>This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
1720      * {@link Collector.Characteristics#UNORDERED unordered} Collector.
1721      *
1722      * @param <T> the type of the input elements
1723      * @param <K> the output type of the key mapping function
1724      * @param <U> the output type of the value mapping function
1725      * @param keyMapper the mapping function to produce keys
1726      * @param valueMapper the mapping function to produce values
1727      * @return a concurrent, unordered {@code Collector} which collects elements into a
1728      * {@code ConcurrentMap} whose keys are the result of applying a key mapping
1729      * function to the input elements, and whose values are the result of
1730      * applying a value mapping function to the input elements
1731      *
1732      * @see #toMap(Function, Function)
1733      * @see #toConcurrentMap(Function, Function, BinaryOperator)
1734      * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
1735      */
1736     public static <T, K, U>
1737     Collector<T, ?, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
1738                                                         Function<? super T, ? extends U> valueMapper) {
1739         return new CollectorImpl<>(size -> new ConcurrentHashMap<>((int) Math.ceil(size / .75), .75f),
1740                                    ConcurrentHashMap::new,
1741                                    uniqKeysMapAccumulator(keyMapper, valueMapper),
1742                                    uniqKeysMapMerger(),
1743                                    CH_CONCURRENT_ID);
1744     }
1745 
1746     /**
1747      * Returns a concurrent {@code Collector} that accumulates elements into a
1748      * {@code ConcurrentMap} whose keys and values are the result of applying
1749      * the provided mapping functions to the input elements.
1750      *
1751      * <p>If the mapped keys contain duplicates (according to {@link Object#equals(Object)}),
1752      * the value mapping function is applied to each equal element, and the
1753      * results are merged using the provided merging function.
1754      *
1755      * <p>There are no guarantees on the type, mutability, or serializability
1756      * of the {@code ConcurrentMap} returned.
1757      *
1758      * @apiNote
1759      * There are multiple ways to deal with collisions between multiple elements
1760      * mapping to the same key.  The other forms of {@code toConcurrentMap} simply use


1938      * @return a {@code Collector} which aggregates the results of two supplied collectors.
1939      * @since 12
1940      */
1941     public static <T, R1, R2, R>
1942     Collector<T, ?, R> teeing(Collector<? super T, ?, R1> downstream1,
1943                               Collector<? super T, ?, R2> downstream2,
1944                               BiFunction<? super R1, ? super R2, R> merger) {
1945         return teeing0(downstream1, downstream2, merger);
1946     }
1947 
1948     private static <T, A1, A2, R1, R2, R>
1949     Collector<T, ?, R> teeing0(Collector<? super T, A1, R1> downstream1,
1950                                Collector<? super T, A2, R2> downstream2,
1951                                BiFunction<? super R1, ? super R2, R> merger) {
1952         Objects.requireNonNull(downstream1, "downstream1");
1953         Objects.requireNonNull(downstream2, "downstream2");
1954         Objects.requireNonNull(merger, "merger");
1955 
1956         Supplier<A1> c1Supplier = Objects.requireNonNull(downstream1.supplier(), "downstream1 supplier");
1957         Supplier<A2> c2Supplier = Objects.requireNonNull(downstream2.supplier(), "downstream2 supplier");
1958         IntFunction<A1> c1SizedSupplier =
1959                 Objects.requireNonNull(downstream1.sizedSupplier(), "downstream1 sizedSupplier");
1960         IntFunction<A2> c2SizedSupplier =
1961                 Objects.requireNonNull(downstream2.sizedSupplier(), "downstream2 sizedSupplier");
1962         BiConsumer<A1, ? super T> c1Accumulator =
1963                 Objects.requireNonNull(downstream1.accumulator(), "downstream1 accumulator");
1964         BiConsumer<A2, ? super T> c2Accumulator =
1965                 Objects.requireNonNull(downstream2.accumulator(), "downstream2 accumulator");
1966         BinaryOperator<A1> c1Combiner = Objects.requireNonNull(downstream1.combiner(), "downstream1 combiner");
1967         BinaryOperator<A2> c2Combiner = Objects.requireNonNull(downstream2.combiner(), "downstream2 combiner");
1968         Function<A1, R1> c1Finisher = Objects.requireNonNull(downstream1.finisher(), "downstream1 finisher");
1969         Function<A2, R2> c2Finisher = Objects.requireNonNull(downstream2.finisher(), "downstream2 finisher");
1970 
1971         Set<Collector.Characteristics> characteristics;
1972         Set<Collector.Characteristics> c1Characteristics = downstream1.characteristics();
1973         Set<Collector.Characteristics> c2Characteristics = downstream2.characteristics();
1974         if (CH_ID.containsAll(c1Characteristics) || CH_ID.containsAll(c2Characteristics)) {
1975             characteristics = CH_NOID;
1976         } else {
1977             EnumSet<Collector.Characteristics> c = EnumSet.noneOf(Collector.Characteristics.class);
1978             c.addAll(c1Characteristics);
1979             c.retainAll(c2Characteristics);
1980             c.remove(Collector.Characteristics.IDENTITY_FINISH);
1981             characteristics = Collections.unmodifiableSet(c);
1982         }
1983 
1984         class PairBox {
1985             A1 left;
1986             A2 right;
1987 
1988             PairBox(int initialSize) {
1989                 left = c1SizedSupplier.apply(initialSize);
1990                 right = c2SizedSupplier.apply(initialSize);
1991             }
1992 
1993             PairBox() {
1994                 left = c1Supplier.get();
1995                 right = c2Supplier.get();
1996             }
1997 
1998             void add(T t) {
1999                 c1Accumulator.accept(left, t);
2000                 c2Accumulator.accept(right, t);
2001             }
2002 
2003             PairBox combine(PairBox other) {
2004                 left = c1Combiner.apply(left, other.left);
2005                 right = c2Combiner.apply(right, other.right);
2006                 return this;
2007             }
2008 
2009             R get() {
2010                 R1 r1 = c1Finisher.apply(left);
2011                 R2 r2 = c2Finisher.apply(right);
2012                 return merger.apply(r1, r2);
2013             }
2014         }
2015 
2016         return new CollectorImpl<>(PairBox::new,
2017                                    PairBox::new,
2018                                    PairBox::add,
2019                                    PairBox::combine,
2020                                    PairBox::get,
2021                                    characteristics);
2022     }
2023 
2024     /**
2025      * Implementation class used by partitioningBy.
2026      */
2027     private static final class Partition<T>
2028             extends AbstractMap<Boolean, T>
2029             implements Map<Boolean, T> {
2030         final T forTrue;
2031         final T forFalse;
2032 
2033         Partition(T forTrue, T forFalse) {
2034             this.forTrue = forTrue;
2035             this.forFalse = forFalse;
2036         }
2037 
2038         @Override
2039         public Set<Map.Entry<Boolean, T>> entrySet() {
2040             return new AbstractSet<>() {
2041                 @Override
< prev index next >