< prev index next >

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

Print this page

        

@@ -43,20 +43,11 @@
 import java.util.Optional;
 import java.util.Set;
 import java.util.StringJoiner;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
-import java.util.function.BiConsumer;
-import java.util.function.BiFunction;
-import java.util.function.BinaryOperator;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.function.Supplier;
-import java.util.function.ToDoubleFunction;
-import java.util.function.ToIntFunction;
-import java.util.function.ToLongFunction;
+import java.util.function.*;
 
 /**
  * Implementations of {@link Collector} that implement various useful reduction
  * operations, such as accumulating elements into collections, summarizing
  * elements according to various criteria, etc.

@@ -191,28 +182,47 @@
      *
      * @param <T> the type of elements to be collected
      * @param <R> the type of the result
      */
     static class CollectorImpl<T, A, R> implements Collector<T, A, R> {
+        private final IntFunction<A> sizedSupplier;
         private final Supplier<A> supplier;
         private final BiConsumer<A, T> accumulator;
         private final BinaryOperator<A> combiner;
         private final Function<A, R> finisher;
         private final Set<Characteristics> characteristics;
 
-        CollectorImpl(Supplier<A> supplier,
+        CollectorImpl(IntFunction<A> sizedSupplier,
+                      Supplier<A> supplier,
                       BiConsumer<A, T> accumulator,
                       BinaryOperator<A> combiner,
                       Function<A,R> finisher,
                       Set<Characteristics> characteristics) {
+            this.sizedSupplier = sizedSupplier;
             this.supplier = supplier;
             this.accumulator = accumulator;
             this.combiner = combiner;
             this.finisher = finisher;
             this.characteristics = characteristics;
         }
 
+        CollectorImpl(IntFunction<A> sizedSupplier,
+                      Supplier<A> supplier,
+                      BiConsumer<A, T> accumulator,
+                      BinaryOperator<A> combiner,
+                      Set<Characteristics> characteristics) {
+            this(sizedSupplier, supplier, accumulator, combiner, castingIdentity(), characteristics);
+        }
+
+        CollectorImpl(Supplier<A> supplier,
+                      BiConsumer<A, T> accumulator,
+                      BinaryOperator<A> combiner,
+                      Function<A,R> finisher,
+                      Set<Characteristics> characteristics) {
+            this(ignored -> supplier.get(), supplier, accumulator, combiner, finisher, characteristics);
+        }
+
         CollectorImpl(Supplier<A> supplier,
                       BiConsumer<A, T> accumulator,
                       BinaryOperator<A> combiner,
                       Set<Characteristics> characteristics) {
             this(supplier, accumulator, combiner, castingIdentity(), characteristics);

@@ -227,10 +237,15 @@
         public Supplier<A> supplier() {
             return supplier;
         }
 
         @Override
+        public IntFunction<A> sizedSupplier() {
+            return sizedSupplier;
+        }
+
+        @Override
         public BinaryOperator<A> combiner() {
             return combiner;
         }
 
         @Override

@@ -273,11 +288,13 @@
      * @return a {@code Collector} which collects all the input elements into a
      * {@code List}, in encounter order
      */
     public static <T>
     Collector<T, ?, List<T>> toList() {
-        return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
+        return new CollectorImpl<>((IntFunction<List<T>>) ArrayList::new,
+                                   (Supplier<List<T>>) ArrayList::new,
+                                   List::add,
                                    (left, right) -> { left.addAll(right); return left; },
                                    CH_ID);
     }
 
     /**

@@ -292,11 +309,13 @@
      * @since 10
      */
     @SuppressWarnings("unchecked")
     public static <T>
     Collector<T, ?, List<T>> toUnmodifiableList() {
-        return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
+        return new CollectorImpl<>((IntFunction<List<T>>) ArrayList::new,
+                                   (Supplier<List<T>>) ArrayList::new,
+                                   List::add,
                                    (left, right) -> { left.addAll(right); return left; },
                                    list -> (List<T>)List.of(list.toArray()),
                                    CH_NOID);
     }
 

@@ -364,11 +383,11 @@
      * @return a {@code Collector} that concatenates the input elements into a
      * {@code String}, in encounter order
      */
     public static Collector<CharSequence, ?, String> joining() {
         return new CollectorImpl<CharSequence, StringBuilder, String>(
-                StringBuilder::new, StringBuilder::append,
+                StringBuilder::new, StringBuilder::new, StringBuilder::append,
                 (r1, r2) -> { r1.append(r2); return r1; },
                 StringBuilder::toString, CH_NOID);
     }
 
     /**

@@ -455,11 +474,11 @@
      */
     public static <T, U, A, R>
     Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper,
                                Collector<? super U, A, R> downstream) {
         BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
-        return new CollectorImpl<>(downstream.supplier(),
+        return new CollectorImpl<>(downstream.sizedSupplier(), downstream.supplier(),
                                    (r, t) -> downstreamAccumulator.accept(r, mapper.apply(t)),
                                    downstream.combiner(), downstream.finisher(),
                                    downstream.characteristics());
     }
 

@@ -500,11 +519,11 @@
      */
     public static <T, U, A, R>
     Collector<T, ?, R> flatMapping(Function<? super T, ? extends Stream<? extends U>> mapper,
                                    Collector<? super U, A, R> downstream) {
         BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
-        return new CollectorImpl<>(downstream.supplier(),
+        return new CollectorImpl<>(downstream.sizedSupplier(), downstream.supplier(),
                             (r, t) -> {
                                 try (Stream<? extends U> result = mapper.apply(t)) {
                                     if (result != null)
                                         result.sequential().forEach(u -> downstreamAccumulator.accept(r, u));
                                 }

@@ -550,11 +569,11 @@
      */
     public static <T, A, R>
     Collector<T, ?, R> filtering(Predicate<? super T> predicate,
                                  Collector<? super T, A, R> downstream) {
         BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
-        return new CollectorImpl<>(downstream.supplier(),
+        return new CollectorImpl<>(downstream.sizedSupplier(), downstream.supplier(),
                                    (r, t) -> {
                                        if (predicate.test(t)) {
                                            downstreamAccumulator.accept(r, t);
                                        }
                                    },

@@ -591,11 +610,12 @@
                 characteristics = EnumSet.copyOf(characteristics);
                 characteristics.remove(Collector.Characteristics.IDENTITY_FINISH);
                 characteristics = Collections.unmodifiableSet(characteristics);
             }
         }
-        return new CollectorImpl<>(downstream.supplier(),
+        return new CollectorImpl<>(downstream.sizedSupplier(),
+                                   downstream.supplier(),
                                    downstream.accumulator(),
                                    downstream.combiner(),
                                    downstream.finisher().andThen(finisher),
                                    characteristics);
     }

@@ -1455,10 +1475,11 @@
      */
     public static <T, K, U>
     Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                     Function<? super T, ? extends U> valueMapper) {
         return new CollectorImpl<>(HashMap::new,
+                                   HashMap::new,
                                    uniqKeysMapAccumulator(keyMapper, valueMapper),
                                    uniqKeysMapMerger(),
                                    CH_ID);
     }
 

@@ -1714,10 +1735,11 @@
      */
     public static <T, K, U>
     Collector<T, ?, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
                                                         Function<? super T, ? extends U> valueMapper) {
         return new CollectorImpl<>(ConcurrentHashMap::new,
+                                   ConcurrentHashMap::new,
                                    uniqKeysMapAccumulator(keyMapper, valueMapper),
                                    uniqKeysMapMerger(),
                                    CH_CONCURRENT_ID);
     }
 

@@ -1929,12 +1951,10 @@
                                BiFunction<? super R1, ? super R2, R> merger) {
         Objects.requireNonNull(downstream1, "downstream1");
         Objects.requireNonNull(downstream2, "downstream2");
         Objects.requireNonNull(merger, "merger");
 
-        Supplier<A1> c1Supplier = Objects.requireNonNull(downstream1.supplier(), "downstream1 supplier");
-        Supplier<A2> c2Supplier = Objects.requireNonNull(downstream2.supplier(), "downstream2 supplier");
         BiConsumer<A1, ? super T> c1Accumulator =
                 Objects.requireNonNull(downstream1.accumulator(), "downstream1 accumulator");
         BiConsumer<A2, ? super T> c2Accumulator =
                 Objects.requireNonNull(downstream2.accumulator(), "downstream2 accumulator");
         BinaryOperator<A1> c1Combiner = Objects.requireNonNull(downstream1.combiner(), "downstream1 combiner");

@@ -1954,12 +1974,24 @@
             c.remove(Collector.Characteristics.IDENTITY_FINISH);
             characteristics = Collections.unmodifiableSet(c);
         }
 
         class PairBox {
-            A1 left = c1Supplier.get();
-            A2 right = c2Supplier.get();
+            A1 left;
+            A2 right;
+
+            PairBox(int initialSize) {
+                left = Objects.requireNonNull(downstream1.sizedSupplier(), "downstream1 sizedSupplier")
+                        .apply(initialSize);
+                right = Objects.requireNonNull(downstream2.sizedSupplier(), "downstream2 sizedSupplier")
+                        .apply(initialSize);
+            }
+
+            PairBox() {
+                left = Objects.requireNonNull(downstream1.supplier(), "downstream1 supplier").get();
+                right = Objects.requireNonNull(downstream2.supplier(), "downstream2 supplier").get();
+            }
 
             void add(T t) {
                 c1Accumulator.accept(left, t);
                 c2Accumulator.accept(right, t);
             }

@@ -1975,11 +2007,16 @@
                 R2 r2 = c2Finisher.apply(right);
                 return merger.apply(r1, r2);
             }
         }
 
-        return new CollectorImpl<>(PairBox::new, PairBox::add, PairBox::combine, PairBox::get, characteristics);
+        return new CollectorImpl<>(PairBox::new,
+                                   PairBox::new,
+                                   PairBox::add,
+                                   PairBox::combine,
+                                   PairBox::get,
+                                   characteristics);
     }
 
     /**
      * Implementation class used by partitioningBy.
      */
< prev index next >