changeset 8238:d23f3aba300d

Fix TabulatorTest after making concurrent map collectors unordered
author briangoetz
date Wed, 17 Apr 2013 00:20:50 -0400
parents 09e54484c80a
children 344772588886
files src/share/classes/java/util/stream/Collectors.java test-ng/tests/org/openjdk/tests/java/util/stream/TabulatorsTest.java
diffstat 2 files changed, 87 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/stream/Collectors.java	Tue Apr 16 19:47:46 2013 -0400
+++ b/src/share/classes/java/util/stream/Collectors.java	Wed Apr 17 00:20:50 2013 -0400
@@ -125,6 +125,8 @@
      *
      * @param <T> The type of input arguments to the merge function
      * @return A merge function which always throw {@code IllegalStateException}
+     * @see #firstWinsMerger()
+     * @see #lastWinsMerger()
      */
     public static<T> BinaryOperator<T> throwingMerger() {
         return (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); };
@@ -138,6 +140,8 @@
      *
      * @param <T> The type of input arguments to the merge function
      * @return A merge function which always returns its first argument
+     * @see #lastWinsMerger()
+     * @see #throwingMerger()
      */
     public static<T> BinaryOperator<T> firstWinsMerger() {
         return (u,v) -> u;
@@ -151,6 +155,8 @@
      *
      * @param <T> The type of input arguments to the merge function
      * @return A merge function which always returns its second argument
+     * @see #firstWinsMerger()
+     * @see #throwingMerger()
      */
     public static<T> BinaryOperator<T> lastWinsMerger() {
         return (u,v) -> v;
@@ -281,7 +287,7 @@
 
     /**
      * Returns a {@code Collector} that concatenates the input elements into a
-     * new {@code StringBuilder}.
+     * new {@link StringBuilder}.
      *
      * @return A {@code Collector} which collects String elements into a
      * {@code StringBuilder}, in encounter order
@@ -295,7 +301,7 @@
 
     /**
      * Returns a {@code Collector} that concatenates the input elements into a
-     * new {@code StringJoiner}, using the specified separator.
+     * new {@link StringJoiner}, using the specified separator.
      *
      * @return A {@code Collector} which collects String elements into a
      * {@code StringJoiner}, in encounter order
@@ -446,6 +452,7 @@
      *                 that is returned when there are no input elements)
      * @param op A {@code BinaryOperator<T>} used to reduce the input elements
      * @return A {@code Collector} which implements the reduction operation
+     * @see #reducing(BinaryOperator)
      * @see #reducing(Object, Function, BinaryOperator)
      */
     public static <T> Collector<T, T>
@@ -473,6 +480,7 @@
      * }</pre>
      * @param op A {@code BinaryOperator<T>} used to reduce the input elements
      * @return A {@code Collector} which implements the reduction operation
+     * @see #reducing(Object, BinaryOperator)
      * @see #reducing(Object, Function, BinaryOperator)
      */
     public static <T> Collector<T, T>
@@ -509,6 +517,7 @@
      * @param <U> The type of the mapped values
      * @return A {@code Collector} implementing the map-reduce operation
      * @see #reducing(Object, BinaryOperator)
+     * @see #reducing(BinaryOperator)
      */
     public static <T, U>
     Collector<T, U> reducing(U identity,
@@ -525,19 +534,27 @@
      * classification function.
      *
      * <p>The classification function maps elements to some key type {@code K}.
-     * The collector produces a {@code Map<K, List<T>>} whose keys are the set
-     * of values resulting from applying the classification function to the input
+     * The collector produces a {@code Map<K, List<T>>} whose keys are the
+     * values resulting from applying the classification function to the input
      * elements, and whose corresponding values are {@code List}s containing the
      * input elements which map to the associated key under the classification
      * function.
      *
-     * <p>No guarantees are made as to the type of the {@code Map} or
-     * {@code List} objects.
+     * <p>There are no guarantees on the type, mutability, serializability, or
+     * thread-safety of the {@code Map} or {@code List} objects returned.
+     * @implSpec
+     * This produces a result similar to:
+     * <pre>{@code
+     *     groupingBy(classifier, toList());
+     * }</pre>
      *
      * @param classifier The classifier function mapping input elements to keys
      * @param <T> The type of the input elements
      * @param <K> The type of the keys
      * @return A {@code Collector} implementing the group-by operation
+     * @see #groupingBy(Function, Collector)
+     * @see #groupingBy(Function, Supplier, Collector)
+     * @see #groupingByConcurrent(Function)
      */
     public static<T, K>
     Collector<T, Map<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier) {
@@ -563,7 +580,8 @@
      *                                              mapping(Person::getLastName, toSet())));
      * }</pre>
      *
-     * <p>No guarantees are made as to the type of the resulting {@code Map}.
+     * There are no guarantees on the type, mutability,
+     * serializability, or thread-safety of the {@code Map} returned.
      *
      * @param classifier The classifier function mapping input elements to keys
      * @param downstream A {@code Collector} implementing the downstream reduction
@@ -571,6 +589,9 @@
      * @param <K> The type of the keys
      * @param <D> The result type of the downstream reduction
      * @return A {@code Collector} implementing the cascaded group-by operation
+     * @see #groupingBy(Function)
+     * @see #groupingBy(Function, Supplier, Collector)
+     * @see #groupingByConcurrent(Function, Collector)
      */
     public static<T, K, D>
     Collector<T, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,
@@ -607,6 +628,9 @@
      * @param <K> The type of the keys
      * @param <D> The result type of the downstream reduction
      * @return A {@code Collector} implementing the cascaded group-by operation
+     * @see #groupingBy(Function, Collector)
+     * @see #groupingBy(Function)
+     * @see #groupingByConcurrent(Function, Supplier, Collector)
      */
     public static<T, K, D, M extends Map<K, D>>
     Collector<T, M> groupingBy(Function<? super T, ? extends K> classifier,
@@ -634,19 +658,27 @@
      * {@link Collector.Characteristics#UNORDERED unordered} Collector.
      *
      * <p>The classification function maps elements to some key type {@code K}.
-     * The collector produces a {@code ConcurrentMap<K, List<T>>} whose keys are the set
-     * of values resulting from applying the classification function to the input
+     * The collector produces a {@code ConcurrentMap<K, List<T>>} whose keys are the
+     * values resulting from applying the classification function to the input
      * elements, and whose corresponding values are {@code List}s containing the
      * input elements which map to the associated key under the classification
      * function.
      *
-     * <p>No guarantees are made as to the type of the {@code Map} or
-     * {@code List} objects.
+     * <p>There are no guarantees on the type, mutability, serializability, or
+     * thread-safety of the {@code Map} or {@code List} objects returned.
+     * @implSpec
+     * This produces a result similar to:
+     * <pre>{@code
+     *     groupingByConcurrent(classifier, toList());
+     * }</pre>
      *
      * @param classifier The classifier function mapping input elements to keys
      * @param <T> The type of the input elements
      * @param <K> The type of the keys
      * @return A {@code Collector} implementing the group-by operation
+     * @see #groupingBy(Function)
+     * @see #groupingByConcurrent(Function, Collector)
+     * @see #groupingByConcurrent(Function, Supplier, Collector)
      */
     public static<T, K>
     Collector<T, ConcurrentMap<K, List<T>>> groupingByConcurrent(Function<? super T, ? extends K> classifier) {
@@ -682,6 +714,9 @@
      * @param <K> The type of the keys
      * @param <D> The result type of the downstream reduction
      * @return A {@code Collector} implementing the cascaded group-by operation
+     * @see #groupingBy(Function, Collector)
+     * @see #groupingByConcurrent(Function)
+     * @see #groupingByConcurrent(Function, Supplier, Collector)
      */
     public static<T, K, D>
     Collector<T, ConcurrentMap<K, D>> groupingByConcurrent(Function<? super T, ? extends K> classifier,
@@ -720,6 +755,9 @@
      * @param <K> The type of the keys
      * @param <D> The result type of the downstream reduction
      * @return A {@code Collector} implementing the cascaded group-by operation
+     * @see #groupingByConcurrent(Function)
+     * @see #groupingByConcurrent(Function, Collector)
+     * @see #groupingBy(Function, Supplier, Collector)
      */
     public static<T, K, D, M extends ConcurrentMap<K, D>>
     Collector<T, M> groupingByConcurrent(Function<? super T, ? extends K> classifier,
@@ -777,12 +815,13 @@
      * to a {@code Predicate}, and organizes them into a
      * {@code Map<Boolean, List<T>>}.
      *
-     * <p>No guarantee is made as to the type of the returned {@code Map}, and
-     * it is not guaranteed to be mutable.
+     * There are no guarantees on the type, mutability,
+     * serializability, or thread-safety of the {@code Map} returned.
      *
      * @param predicate The predicate used for classifying input elements
      * @param <T> The type of the input elements
      * @return A {@code Collector} implementing the partitioning operation.
+     * @see #partitioningBy(Predicate, Collector)
      */
     public static<T>
     Collector<T, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate) {
@@ -796,14 +835,15 @@
      * {@code Map<Boolean, D>} whose values are the result of the downstream
      * reduction.
      *
-     * <p>No guarantee is made as to the type of the returned {@code Map}, and
-     * it is not guaranteed to be mutable.
+     * There are no guarantees on the type, mutability,
+     * serializability, or thread-safety of the {@code Map} returned.
      *
      * @param predicate The predicate used for classifying input elements
      * @param downstream A {@code Collector} implementing the downstream reduction
      * @param <T> The type of the input elements
      * @param <D> The result type of the downstream reduction
      * @return A {@code Collector} implementing the cascaded partitioning operation.
+     * @see #partitioningBy(Predicate)
      */
     public static<T, D>
     Collector<T, Map<Boolean, D>> partitioningBy(Predicate<? super T> predicate,
@@ -880,6 +920,9 @@
      * @return A {@code Collector} which collects elements into a {@code Map}
      * whose keys and values are the result of applying mapping functions to
      * the input elements
+     * @see #toMap(Function, Function, BinaryOperator)
+     * @see #toMap(Function, Function, BinaryOperator, Supplier)
+     * @see #toConcurrentMap(Function, Function)
      */
     public static <T, K, U>
     Collector<T, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
@@ -923,6 +966,9 @@
      * elements, and whose values are the result of applying a value mapping
      * function to all input elements equal to the key and combining them
      * using the merge function
+     * @see #toMap(Function, Function)
+     * @see #toMap(Function, Function, BinaryOperator, Supplier)
+     * @see #toConcurrentMap(Function, Function, BinaryOperator)
      */
     public static <T, K, U>
     Collector<T, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
@@ -955,6 +1001,8 @@
      * function to all input elements equal to the key and combining them
      * using the merge function
      * @see #toMap(Function, Function)
+     * @see #toMap(Function, Function, BinaryOperator)
+     * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
      */
     public static <T, K, U, M extends Map<K, U>>
     Collector<T, M> toMap(Function<? super T, ? extends K> keyMapper,
@@ -1009,6 +1057,9 @@
      * {@code ConcurrentMap} whose keys are the result of applying a key mapping
      * function to the input elements, and whose values are the result of
      * applying a value mapping function to the input elements
+     * @see #toMap(Function, Function)
+     * @see #toConcurrentMap(Function, Function, BinaryOperator)
+     * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
      */
     public static <T, K, U>
     Collector<T, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
@@ -1056,6 +1107,9 @@
      * function to the input elements, and whose values are the result of
      * applying a value mapping function to all input elements equal to the key
      * and combining them using the merge function
+     * @see #toConcurrentMap(Function, Function)
+     * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
+     * @see #toMap(Function, Function, BinaryOperator)
      */
     public static <T, K, U>
     Collector<T, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
@@ -1090,6 +1144,9 @@
      * function to the input elements, and whose values are the result of
      * applying a value mapping function to all input elements equal to the key
      * and combining them using the merge function
+     * @see #toConcurrentMap(Function, Function)
+     * @see #toConcurrentMap(Function, Function, BinaryOperator)
+     * @see #toMap(Function, Function, BinaryOperator, Supplier)
      */
     public static <T, K, U, M extends ConcurrentMap<K, U>>
     Collector<T, M> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
@@ -1111,7 +1168,8 @@
      * @param mapper The mapping function to apply to each element
      * @param <T> The type of the input elements
      * @return A {@code Collector} implementing the summary-statistics reduction
-     * @see IntSummaryStatistics
+     * @see #toDoubleSummaryStatistics(ToDoubleFunction)
+     * @see #toLongSummaryStatistics(ToLongFunction)
      */
     public static<T>
     Collector<T, IntSummaryStatistics> toIntSummaryStatistics(ToIntFunction<? super T> mapper) {
@@ -1128,7 +1186,8 @@
      * @param mapper The mapping function to apply to each element
      * @param <T> The type of the input elements
      * @return A {@code Collector} implementing the summary-statistics reduction
-     * @see LongSummaryStatistics
+     * @see #toDoubleSummaryStatistics(ToDoubleFunction)
+     * @see #toIntSummaryStatistics(ToIntFunction)
      */
     public static<T>
     Collector<T, LongSummaryStatistics> toLongSummaryStatistics(ToLongFunction<? super T> mapper) {
@@ -1145,7 +1204,8 @@
      * @param mapper The mapping function to apply to each element
      * @param <T> The type of the input elements
      * @return A {@code Collector} implementing the summary-statistics reduction
-     * @see DoubleSummaryStatistics
+     * @see #toLongSummaryStatistics(ToLongFunction)
+     * @see #toIntSummaryStatistics(ToIntFunction)
      */
     public static<T>
     Collector<T, DoubleSummaryStatistics> toDoubleSummaryStatistics(ToDoubleFunction<? super T> mapper) {
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/TabulatorsTest.java	Tue Apr 16 19:47:46 2013 -0400
+++ b/test-ng/tests/org/openjdk/tests/java/util/stream/TabulatorsTest.java	Wed Apr 17 00:20:50 2013 -0400
@@ -205,11 +205,12 @@
     private<T, M extends Map> void exerciseMapTabulation(StreamTestData<T> data,
                                                          Collector<T, ? extends M> collector,
                                                          TabulationAssertion<T, M> assertion) throws ReflectiveOperationException {
+        boolean ordered = data.isOrdered() && !collector.characteristics().contains(Collector.Characteristics.UNORDERED);
         M m = withData(data)
                 .terminal(s -> s.collect(collector))
-                .parallelEqualityAsserter(data.isOrdered() ? LambdaTestHelpers::assertContentsEqual : this::nestedMapEqualityAssertion)
+                .parallelEqualityAsserter(ordered ? LambdaTestHelpers::assertContentsEqual : this::nestedMapEqualityAssertion)
                 .exercise();
-        assertion.assertValue(m, () -> data.stream(), data.isOrdered());
+        assertion.assertValue(m, () -> data.stream(), ordered);
         m = withData(data)
                 .terminal(s -> s.unordered().collect(collector))
                 .parallelEqualityAsserter(this::nestedMapEqualityAssertion)
@@ -237,9 +238,12 @@
         Function<Integer, Integer> classifier = i -> i % 3;
 
         // Single-level groupBy
-        exerciseMapTabulation(data, groupingBy(classifier), new GroupedMapAssertion<>(classifier, HashMap.class, new ListAssertion<>()));
-        exerciseMapTabulation(data, groupingByConcurrent(classifier), new GroupedMapAssertion<>(classifier, ConcurrentHashMap.class,
-                                                                                                new ListAssertion<>()));
+        exerciseMapTabulation(data, groupingBy(classifier),
+                              new GroupedMapAssertion<>(classifier, HashMap.class,
+                                                        new ListAssertion<>()));
+        exerciseMapTabulation(data, groupingByConcurrent(classifier),
+                              new GroupedMapAssertion<>(classifier, ConcurrentHashMap.class,
+                                                        new ListAssertion<>()));
 
         // With explicit constructors
         exerciseMapTabulation(data,