< prev index next >

test/jdk/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectorsTest.java

Print this page


   1 /*
   2  * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.openjdk.tests.java.util.stream;
  24 
  25 import java.util.ArrayList;
  26 import java.util.Arrays;
  27 import java.util.Collection;
  28 import java.util.Collections;
  29 import java.util.Comparator;
  30 import java.util.HashMap;
  31 import java.util.HashSet;

  32 import java.util.Iterator;
  33 import java.util.List;
  34 import java.util.Map;
  35 import java.util.Optional;
  36 import java.util.Set;
  37 import java.util.StringJoiner;
  38 import java.util.TreeMap;
  39 import java.util.concurrent.ConcurrentHashMap;
  40 import java.util.concurrent.ConcurrentSkipListMap;
  41 import java.util.concurrent.atomic.AtomicInteger;

  42 import java.util.function.BinaryOperator;
  43 import java.util.function.Function;
  44 import java.util.function.Predicate;
  45 import java.util.function.Supplier;
  46 import java.util.stream.Collector;
  47 import java.util.stream.Collectors;
  48 import java.util.stream.LambdaTestHelpers;
  49 import java.util.stream.OpTestCase;
  50 import java.util.stream.Stream;
  51 import java.util.stream.StreamOpFlagTestHelper;
  52 import java.util.stream.StreamTestDataProvider;
  53 import java.util.stream.TestData;
  54 
  55 import org.testng.annotations.Test;
  56 
  57 import static java.util.stream.Collectors.collectingAndThen;
  58 import static java.util.stream.Collectors.flatMapping;
  59 import static java.util.stream.Collectors.filtering;
  60 import static java.util.stream.Collectors.groupingBy;
  61 import static java.util.stream.Collectors.groupingByConcurrent;


  79 public class CollectorsTest extends OpTestCase {
  80 
  81     private abstract static class CollectorAssertion<T, U> {
  82         abstract void assertValue(U value,
  83                                   Supplier<Stream<T>> source,
  84                                   boolean ordered) throws ReflectiveOperationException;
  85     }
  86 
  87     static class MappingAssertion<T, V, R> extends CollectorAssertion<T, R> {
  88         private final Function<T, V> mapper;
  89         private final CollectorAssertion<V, R> downstream;
  90 
  91         MappingAssertion(Function<T, V> mapper, CollectorAssertion<V, R> downstream) {
  92             this.mapper = mapper;
  93             this.downstream = downstream;
  94         }
  95 
  96         @Override
  97         void assertValue(R value, Supplier<Stream<T>> source, boolean ordered) throws ReflectiveOperationException {
  98             downstream.assertValue(value,
  99                                    () -> source.get().map(mapper::apply),
 100                                    ordered);
 101         }
 102     }
 103 
 104     static class FlatMappingAssertion<T, V, R> extends CollectorAssertion<T, R> {
 105         private final Function<T, Stream<V>> mapper;
 106         private final CollectorAssertion<V, R> downstream;
 107 
 108         FlatMappingAssertion(Function<T, Stream<V>> mapper,
 109                              CollectorAssertion<V, R> downstream) {
 110             this.mapper = mapper;
 111             this.downstream = downstream;
 112         }
 113 
 114         @Override
 115         void assertValue(R value, Supplier<Stream<T>> source, boolean ordered) throws ReflectiveOperationException {
 116             downstream.assertValue(value,
 117                                    () -> source.get().flatMap(mapper::apply),
 118                                    ordered);
 119         }
 120     }
 121 
 122     static class FilteringAssertion<T, R> extends CollectorAssertion<T, R> {
 123         private final Predicate<T> filter;
 124         private final CollectorAssertion<T, R> downstream;
 125 
 126         public FilteringAssertion(Predicate<T> filter, CollectorAssertion<T, R> downstream) {
 127             this.filter = filter;
 128             this.downstream = downstream;
 129         }
 130 
 131         @Override
 132         void assertValue(R value, Supplier<Stream<T>> source, boolean ordered) throws ReflectiveOperationException {
 133             downstream.assertValue(value,
 134                                    () -> source.get().filter(filter),
 135                                    ordered);
 136         }
 137     }


 270             this.identity = identity;
 271             this.mapper = mapper;
 272             this.reducer = reducer;
 273         }
 274 
 275         @Override
 276         void assertValue(U value, Supplier<Stream<T>> source, boolean ordered)
 277                 throws ReflectiveOperationException {
 278             Optional<U> reduced = source.get().map(mapper).reduce(reducer);
 279             if (value == null)
 280                 assertTrue(!reduced.isPresent());
 281             else if (!reduced.isPresent()) {
 282                 assertEquals(value, identity);
 283             }
 284             else {
 285                 assertEquals(value, reduced.get());
 286             }
 287         }
 288     }
 289 





















 290     private <T> ResultAsserter<T> mapTabulationAsserter(boolean ordered) {
 291         return (act, exp, ord, par) -> {
 292             if (par && (!ordered || !ord)) {
 293                 CollectorsTest.nestedMapEqualityAssertion(act, exp);
 294             }
 295             else {
 296                 LambdaTestHelpers.assertContentsEqual(act, exp);
 297             }
 298         };
 299     }
 300 
 301     private<T, M extends Map>
 302     void exerciseMapCollection(TestData<T, Stream<T>> data,
 303                                Collector<T, ?, ? extends M> collector,
 304                                CollectorAssertion<T, M> assertion)
 305             throws ReflectiveOperationException {
 306         boolean ordered = !collector.characteristics().contains(Collector.Characteristics.UNORDERED);
 307 
 308         M m = withData(data)
 309                 .terminal(s -> s.collect(collector))


 729 
 730         // Two level partition with reduce
 731         exerciseMapCollection(data,
 732                               partitioningBy(classifier, reducing(0, Integer::sum)),
 733                               new PartitioningByAssertion<>(classifier,
 734                                                             new ReducingAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
 735     }
 736 
 737     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
 738     public void testComposeFinisher(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
 739         List<Integer> asList = exerciseTerminalOps(data, s -> s.collect(toList()));
 740         List<Integer> asImmutableList = exerciseTerminalOps(data, s -> s.collect(collectingAndThen(toList(), Collections::unmodifiableList)));
 741         assertEquals(asList, asImmutableList);
 742         try {
 743             asImmutableList.add(0);
 744             fail("Expecting immutable result");
 745         }
 746         catch (UnsupportedOperationException ignored) { }
 747     }
 748 






































 749 }
   1 /*
   2  * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.openjdk.tests.java.util.stream;
  24 
  25 import java.util.ArrayList;
  26 import java.util.Arrays;
  27 import java.util.Collection;
  28 import java.util.Collections;
  29 import java.util.Comparator;
  30 import java.util.HashMap;
  31 import java.util.HashSet;
  32 import java.util.IntSummaryStatistics;
  33 import java.util.Iterator;
  34 import java.util.List;
  35 import java.util.Map;
  36 import java.util.Optional;
  37 import java.util.Set;
  38 import java.util.StringJoiner;
  39 import java.util.TreeMap;
  40 import java.util.concurrent.ConcurrentHashMap;
  41 import java.util.concurrent.ConcurrentSkipListMap;
  42 import java.util.concurrent.atomic.AtomicInteger;
  43 import java.util.function.BiFunction;
  44 import java.util.function.BinaryOperator;
  45 import java.util.function.Function;
  46 import java.util.function.Predicate;
  47 import java.util.function.Supplier;
  48 import java.util.stream.Collector;
  49 import java.util.stream.Collectors;
  50 import java.util.stream.LambdaTestHelpers;
  51 import java.util.stream.OpTestCase;
  52 import java.util.stream.Stream;
  53 import java.util.stream.StreamOpFlagTestHelper;
  54 import java.util.stream.StreamTestDataProvider;
  55 import java.util.stream.TestData;
  56 
  57 import org.testng.annotations.Test;
  58 
  59 import static java.util.stream.Collectors.collectingAndThen;
  60 import static java.util.stream.Collectors.flatMapping;
  61 import static java.util.stream.Collectors.filtering;
  62 import static java.util.stream.Collectors.groupingBy;
  63 import static java.util.stream.Collectors.groupingByConcurrent;


  81 public class CollectorsTest extends OpTestCase {
  82 
  83     private abstract static class CollectorAssertion<T, U> {
  84         abstract void assertValue(U value,
  85                                   Supplier<Stream<T>> source,
  86                                   boolean ordered) throws ReflectiveOperationException;
  87     }
  88 
  89     static class MappingAssertion<T, V, R> extends CollectorAssertion<T, R> {
  90         private final Function<T, V> mapper;
  91         private final CollectorAssertion<V, R> downstream;
  92 
  93         MappingAssertion(Function<T, V> mapper, CollectorAssertion<V, R> downstream) {
  94             this.mapper = mapper;
  95             this.downstream = downstream;
  96         }
  97 
  98         @Override
  99         void assertValue(R value, Supplier<Stream<T>> source, boolean ordered) throws ReflectiveOperationException {
 100             downstream.assertValue(value,
 101                                    () -> source.get().map(mapper),
 102                                    ordered);
 103         }
 104     }
 105 
 106     static class FlatMappingAssertion<T, V, R> extends CollectorAssertion<T, R> {
 107         private final Function<T, Stream<V>> mapper;
 108         private final CollectorAssertion<V, R> downstream;
 109 
 110         FlatMappingAssertion(Function<T, Stream<V>> mapper,
 111                              CollectorAssertion<V, R> downstream) {
 112             this.mapper = mapper;
 113             this.downstream = downstream;
 114         }
 115 
 116         @Override
 117         void assertValue(R value, Supplier<Stream<T>> source, boolean ordered) throws ReflectiveOperationException {
 118             downstream.assertValue(value,
 119                                    () -> source.get().flatMap(mapper),
 120                                    ordered);
 121         }
 122     }
 123 
 124     static class FilteringAssertion<T, R> extends CollectorAssertion<T, R> {
 125         private final Predicate<T> filter;
 126         private final CollectorAssertion<T, R> downstream;
 127 
 128         public FilteringAssertion(Predicate<T> filter, CollectorAssertion<T, R> downstream) {
 129             this.filter = filter;
 130             this.downstream = downstream;
 131         }
 132 
 133         @Override
 134         void assertValue(R value, Supplier<Stream<T>> source, boolean ordered) throws ReflectiveOperationException {
 135             downstream.assertValue(value,
 136                                    () -> source.get().filter(filter),
 137                                    ordered);
 138         }
 139     }


 272             this.identity = identity;
 273             this.mapper = mapper;
 274             this.reducer = reducer;
 275         }
 276 
 277         @Override
 278         void assertValue(U value, Supplier<Stream<T>> source, boolean ordered)
 279                 throws ReflectiveOperationException {
 280             Optional<U> reduced = source.get().map(mapper).reduce(reducer);
 281             if (value == null)
 282                 assertTrue(!reduced.isPresent());
 283             else if (!reduced.isPresent()) {
 284                 assertEquals(value, identity);
 285             }
 286             else {
 287                 assertEquals(value, reduced.get());
 288             }
 289         }
 290     }
 291 
 292     static class DuplexingAssertion<T, R1, R2, RR> extends CollectorAssertion<T, RR> {
 293         private final Collector<T, ?, R1> c1;
 294         private final Collector<T, ?, R2> c2;
 295         private final BiFunction<? super R1, ? super R2, ? extends RR> finisher;
 296 
 297         DuplexingAssertion(Collector<T, ?, R1> c1, Collector<T, ?, R2> c2,
 298                                BiFunction<? super R1, ? super R2, ? extends RR> finisher) {
 299             this.c1 = c1;
 300             this.c2 = c2;
 301             this.finisher = finisher;
 302         }
 303 
 304         @Override
 305         void assertValue(RR value, Supplier<Stream<T>> source, boolean ordered) {
 306             R1 r1 = source.get().collect(c1);
 307             R2 r2 = source.get().collect(c2);
 308             RR expected = finisher.apply(r1, r2);
 309             assertEquals(value, expected);
 310         }
 311     }
 312 
 313     private <T> ResultAsserter<T> mapTabulationAsserter(boolean ordered) {
 314         return (act, exp, ord, par) -> {
 315             if (par && (!ordered || !ord)) {
 316                 CollectorsTest.nestedMapEqualityAssertion(act, exp);
 317             }
 318             else {
 319                 LambdaTestHelpers.assertContentsEqual(act, exp);
 320             }
 321         };
 322     }
 323 
 324     private<T, M extends Map>
 325     void exerciseMapCollection(TestData<T, Stream<T>> data,
 326                                Collector<T, ?, ? extends M> collector,
 327                                CollectorAssertion<T, M> assertion)
 328             throws ReflectiveOperationException {
 329         boolean ordered = !collector.characteristics().contains(Collector.Characteristics.UNORDERED);
 330 
 331         M m = withData(data)
 332                 .terminal(s -> s.collect(collector))


 752 
 753         // Two level partition with reduce
 754         exerciseMapCollection(data,
 755                               partitioningBy(classifier, reducing(0, Integer::sum)),
 756                               new PartitioningByAssertion<>(classifier,
 757                                                             new ReducingAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
 758     }
 759 
 760     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
 761     public void testComposeFinisher(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
 762         List<Integer> asList = exerciseTerminalOps(data, s -> s.collect(toList()));
 763         List<Integer> asImmutableList = exerciseTerminalOps(data, s -> s.collect(collectingAndThen(toList(), Collections::unmodifiableList)));
 764         assertEquals(asList, asImmutableList);
 765         try {
 766             asImmutableList.add(0);
 767             fail("Expecting immutable result");
 768         }
 769         catch (UnsupportedOperationException ignored) { }
 770     }
 771 
 772     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
 773     public void testDuplexing(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
 774         Collector<Integer, ?, Long> summing = Collectors.summingLong(Integer::valueOf);
 775         Collector<Integer, ?, Long> counting = Collectors.counting();
 776         Collector<Integer, ?, Integer> min = collectingAndThen(Collectors.<Integer>minBy(Comparator.naturalOrder()),
 777                 opt -> opt.orElse(Integer.MAX_VALUE));
 778         Collector<Integer, ?, Integer> max = collectingAndThen(Collectors.<Integer>maxBy(Comparator.naturalOrder()),
 779                 opt -> opt.orElse(Integer.MIN_VALUE));
 780         Collector<Integer, ?, String> joining = mapping(String::valueOf, Collectors.joining(", ", "[", "]"));
 781 
 782         Collector<Integer, ?, Map.Entry<Long, Long>> sumAndCount = Collectors.duplexing(summing, counting, Map::entry);
 783         Collector<Integer, ?, Map.Entry<Integer, Integer>> minAndMax = Collectors.duplexing(min, max, Map::entry);
 784         Collector<Integer, ?, Double> averaging = Collectors.duplexing(summing, counting,
 785                 (sum, count) -> ((double)sum) / count);
 786         Collector<Integer, ?, String> summaryStatistics = Collectors.duplexing(sumAndCount, minAndMax,
 787                 (sumCountEntry, minMaxEntry) -> new IntSummaryStatistics(
 788                         sumCountEntry.getValue(), minMaxEntry.getKey(),
 789                         minMaxEntry.getValue(), sumCountEntry.getKey()).toString());
 790         Collector<Integer, ?, String> countAndContent = Collectors.duplexing(counting, joining,
 791                 (count, content) -> count+": "+content);
 792 
 793         assertCollect(data, sumAndCount, stream -> {
 794             List<Integer> list = stream.collect(toList());
 795             return Map.entry(list.stream().mapToLong(Integer::intValue).sum(), (long) list.size());
 796         });
 797         assertCollect(data, averaging, stream -> stream.mapToInt(Integer::intValue).average().orElse(Double.NaN));
 798         assertCollect(data, summaryStatistics,
 799                 stream -> stream.mapToInt(Integer::intValue).summaryStatistics().toString());
 800         assertCollect(data, countAndContent, stream -> {
 801             List<Integer> list = stream.collect(toList());
 802             return list.size()+": "+list;
 803         });
 804 
 805         Function<Integer, Integer> classifier = i -> i % 3;
 806         exerciseMapCollection(data, groupingBy(classifier, sumAndCount),
 807                 new GroupingByAssertion<>(classifier, Map.class,
 808                         new DuplexingAssertion<>(summing, counting, Map::entry)));
 809     }
 810 }
< prev index next >