changeset 8902:567458424515

Add Characteristics... arguments to Collectors.of
author briangoetz
date Wed, 26 Jun 2013 15:38:29 -0400
parents 261442107943
children a35de55b9a42
files src/share/classes/java/util/stream/Collector.java test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java
diffstat 2 files changed, 43 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/stream/Collector.java	Wed Jun 26 08:18:57 2013 -0700
+++ b/src/share/classes/java/util/stream/Collector.java	Wed Jun 26 15:38:29 2013 -0400
@@ -24,6 +24,8 @@
  */
 package java.util.stream;
 
+import java.util.Collections;
+import java.util.EnumSet;
 import java.util.Set;
 import java.util.function.BiConsumer;
 import java.util.function.BinaryOperator;
@@ -221,16 +223,22 @@
      * @param supplier The supplier function for the new collector
      * @param accumulator The accumulator function for the new collector
      * @param combiner The combiner function for the new collector
+     * @param characteristics The collector characteristics for the new
+     *                        collector
      * @param <T> The type of input elements for the new collector
      * @param <R> The type of intermediate accumulation result, and final result,
      *           for the new collector
      * @return the new {@code Collector}
      */
-    static<T, R> Collector<T, R, R> of(Supplier<R> supplier,
-                                       BiConsumer<R, T> accumulator,
-                                       BinaryOperator<R> combiner) {
-        return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, Collectors.CH_ID);
-
+    public static<T, R> Collector<T, R, R> of(Supplier<R> supplier,
+                                              BiConsumer<R, T> accumulator,
+                                              BinaryOperator<R> combiner,
+                                              Characteristics... characteristics) {
+        Set<Characteristics> cs = (characteristics.length == 0)
+                                  ? Collectors.CH_ID
+                                  : Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH,
+                                                                           characteristics));
+        return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, cs);
     }
 
     /**
@@ -240,16 +248,26 @@
      * @param supplier The supplier function for the new collector
      * @param accumulator The accumulator function for the new collector
      * @param combiner The combiner function for the new collector
+     * @param finisher The finisher function for the new collector
+     * @param characteristics The collector characteristics for the new
+     *                        collector
      * @param <T> The type of input elements for the new collector
      * @param <A> The intermediate accumulation type of the new collector
      * @param <R> The final result type of the new collector
      * @return the new {@code Collector}
      */
-    static<T, A, R> Collector<T, A, R> of(Supplier<A> supplier,
-                                          BiConsumer<A, T> accumulator,
-                                          BinaryOperator<A> combiner,
-                                          Function<A, R> finisher) {
-        return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, finisher, Collectors.CH_NOID);
+    public static<T, A, R> Collector<T, A, R> of(Supplier<A> supplier,
+                                                 BiConsumer<A, T> accumulator,
+                                                 BinaryOperator<A> combiner,
+                                                 Function<A, R> finisher,
+                                                 Characteristics... characteristics) {
+        Set<Characteristics> cs = Collectors.CH_NOID;
+        if (characteristics.length > 0) {
+            cs = EnumSet.noneOf(Characteristics.class);
+            Collections.addAll(cs, characteristics);
+            cs = Collections.unmodifiableSet(cs);
+        }
+        return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, finisher, cs);
     }
 
     /**
--- a/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java	Wed Jun 26 08:18:57 2013 -0700
+++ b/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java	Wed Jun 26 15:38:29 2013 -0400
@@ -317,6 +317,21 @@
                       s -> s.mapToLong(x -> x * 2).average().orElse(0));
         assertCollect(data, Collectors.averagingDouble(x -> x * 2),
                       s -> s.mapToDouble(x -> x * 2).average().orElse(0));
+
+        // Test explicit Collector.of
+        Collector<Integer, long[], Double> avg2xint = Collector.of(() -> new long[2],
+                                                                   (a, b) -> {
+                                                                       a[0] += b * 2;
+                                                                       a[1]++;
+                                                                   },
+                                                                   (a, b) -> {
+                                                                       a[0] += b[0];
+                                                                       a[1] += b[1];
+                                                                       return a;
+                                                                   },
+                                                                   a -> a[1] == 0 ? 0.0d : (double) a[0] / a[1]);
+        assertCollect(data, avg2xint,
+                      s -> s.mapToInt(x -> x * 2).average().orElse(0));
     }
 
     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)