1 /*
2  * Copyright (c) 2012, 2017, 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 
24 /*
25  * @test
26  * @summary flat-map operations
27  * @bug 8044047 8076458 8075939
28  */
29 
30 package org.openjdk.tests.java.util.stream;
31 
32 import org.testng.annotations.Test;
33 
34 import java.util.Arrays;
35 import java.util.Collection;
36 import java.util.Collections;
37 import java.util.function.Function;
38 import java.util.stream.*;
39 import java.util.concurrent.atomic.AtomicInteger;
40 
41 import static java.util.stream.LambdaTestHelpers.*;
42 import static java.util.stream.ThowableHelper.checkNPE;
43 
44 @Test
45 public class FlatMapOpTest extends OpTestCase {
46 
47     @Test
testNullMapper()48     public void testNullMapper() {
49         checkNPE(() -> Stream.of(1).flatMap(null));
50         checkNPE(() -> IntStream.of(1).flatMap(null));
51         checkNPE(() -> LongStream.of(1).flatMap(null));
52         checkNPE(() -> DoubleStream.of(1).flatMap(null));
53     }
54 
55     static final Function<Integer, Stream<Integer>> integerRangeMapper
56             = e -> IntStream.range(0, e).boxed();
57 
58     @Test
testFlatMap()59     public void testFlatMap() {
60         String[] stringsArray = {"hello", "there", "", "yada"};
61         Stream<String> strings = Arrays.asList(stringsArray).stream();
62         assertConcat(strings.flatMap(flattenChars).iterator(), "hellothereyada");
63 
64         assertCountSum(countTo(10).stream().flatMap(mfId), 10, 55);
65         assertCountSum(countTo(10).stream().flatMap(mfNull), 0, 0);
66         assertCountSum(countTo(3).stream().flatMap(mfLt), 6, 4);
67 
68         exerciseOps(TestData.Factory.ofArray("stringsArray", stringsArray), s -> s.flatMap(flattenChars));
69         exerciseOps(TestData.Factory.ofArray("LONG_STRING", new String[] {LONG_STRING}), s -> s.flatMap(flattenChars));
70     }
71 
72     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
testOps(String name, TestData.OfRef<Integer> data)73     public void testOps(String name, TestData.OfRef<Integer> data) {
74         Collection<Integer> result = exerciseOps(data, s -> s.flatMap(mfId));
75         assertEquals(data.size(), result.size());
76 
77         result = exerciseOps(data, s -> s.flatMap(mfNull));
78         assertEquals(0, result.size());
79 
80         result = exerciseOps(data, s-> s.flatMap(e -> Stream.empty()));
81         assertEquals(0, result.size());
82     }
83 
84     @Test(dataProvider = "StreamTestData<Integer>.small", dataProviderClass = StreamTestDataProvider.class)
testOpsX(String name, TestData.OfRef<Integer> data)85     public void testOpsX(String name, TestData.OfRef<Integer> data) {
86         exerciseOps(data, s -> s.flatMap(mfLt));
87         exerciseOps(data, s -> s.flatMap(integerRangeMapper));
88         exerciseOps(data, s -> s.flatMap((Integer e) -> IntStream.range(0, e).boxed().limit(10)));
89     }
90 
91     @Test
testOpsShortCircuit()92     public void testOpsShortCircuit() {
93         AtomicInteger count = new AtomicInteger();
94         Stream.of(0).flatMap(i -> IntStream.range(0, 100).boxed()).
95                 peek(i -> count.incrementAndGet()).
96                 limit(10).toArray();
97         assertEquals(count.get(), 10);
98     }
99 
100     //
101 
102     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
testIntOps(String name, TestData.OfInt data)103     public void testIntOps(String name, TestData.OfInt data) {
104         Collection<Integer> result = exerciseOps(data, s -> s.flatMap(IntStream::of));
105         assertEquals(data.size(), result.size());
106         assertContents(data, result);
107 
108         result = exerciseOps(data, s -> s.boxed().flatMapToInt(IntStream::of));
109         assertEquals(data.size(), result.size());
110         assertContents(data, result);
111 
112         result = exerciseOps(data, s -> s.flatMap(i -> IntStream.empty()));
113         assertEquals(0, result.size());
114     }
115 
116     @Test(dataProvider = "IntStreamTestData.small", dataProviderClass = IntStreamTestDataProvider.class)
testIntOpsX(String name, TestData.OfInt data)117     public void testIntOpsX(String name, TestData.OfInt data) {
118         exerciseOps(data, s -> s.flatMap(e -> IntStream.range(0, e)));
119         exerciseOps(data, s -> s.flatMap(e -> IntStream.range(0, e).limit(10)));
120 
121         exerciseOps(data, s -> s.boxed().flatMapToInt(e -> IntStream.range(0, e)));
122         exerciseOps(data, s -> s.boxed().flatMapToInt(e -> IntStream.range(0, e).limit(10)));
123     }
124 
125     @Test
testIntOpsShortCircuit()126     public void testIntOpsShortCircuit() {
127         AtomicInteger count = new AtomicInteger();
128         IntStream.of(0).flatMap(i -> IntStream.range(0, 100)).
129                 peek(i -> count.incrementAndGet()).
130                 limit(10).toArray();
131         assertEquals(count.get(), 10);
132 
133         count.set(0);
134         Stream.of(0).flatMapToInt(i -> IntStream.range(0, 100)).
135                 peek(i -> count.incrementAndGet()).
136                 limit(10).toArray();
137         assertEquals(count.get(), 10);
138     }
139 
140     //
141 
142     @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
testLongOps(String name, TestData.OfLong data)143     public void testLongOps(String name, TestData.OfLong data) {
144         Collection<Long> result = exerciseOps(data, s -> s.flatMap(LongStream::of));
145         assertEquals(data.size(), result.size());
146         assertContents(data, result);
147 
148         result = exerciseOps(data, s -> s.boxed().flatMapToLong(LongStream::of));
149         assertEquals(data.size(), result.size());
150         assertContents(data, result);
151 
152         result = exerciseOps(data, s -> LongStream.empty());
153         assertEquals(0, result.size());
154     }
155 
156     @Test(dataProvider = "LongStreamTestData.small", dataProviderClass = LongStreamTestDataProvider.class)
testLongOpsX(String name, TestData.OfLong data)157     public void testLongOpsX(String name, TestData.OfLong data) {
158         exerciseOps(data, s -> s.flatMap(e -> LongStream.range(0, e)));
159         exerciseOps(data, s -> s.flatMap(e -> LongStream.range(0, e).limit(10)));
160     }
161 
162     @Test
testLongOpsShortCircuit()163     public void testLongOpsShortCircuit() {
164         AtomicInteger count = new AtomicInteger();
165         LongStream.of(0).flatMap(i -> LongStream.range(0, 100)).
166                 peek(i -> count.incrementAndGet()).
167                 limit(10).toArray();
168         assertEquals(count.get(), 10);
169 
170         count.set(0);
171         Stream.of(0).flatMapToLong(i -> LongStream.range(0, 100)).
172                 peek(i -> count.incrementAndGet()).
173                 limit(10).toArray();
174         assertEquals(count.get(), 10);
175     }
176 
177     //
178 
179     @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
testDoubleOps(String name, TestData.OfDouble data)180     public void testDoubleOps(String name, TestData.OfDouble data) {
181         Collection<Double> result = exerciseOps(data, s -> s.flatMap(DoubleStream::of));
182         assertEquals(data.size(), result.size());
183         assertContents(data, result);
184 
185         result = exerciseOps(data, s -> s.boxed().flatMapToDouble(DoubleStream::of));
186         assertEquals(data.size(), result.size());
187         assertContents(data, result);
188 
189         result = exerciseOps(data, s -> DoubleStream.empty());
190         assertEquals(0, result.size());
191     }
192 
193     @Test(dataProvider = "DoubleStreamTestData.small", dataProviderClass = DoubleStreamTestDataProvider.class)
testDoubleOpsX(String name, TestData.OfDouble data)194     public void testDoubleOpsX(String name, TestData.OfDouble data) {
195         exerciseOps(data, s -> s.flatMap(e -> IntStream.range(0, (int) e).asDoubleStream()));
196         exerciseOps(data, s -> s.flatMap(e -> IntStream.range(0, (int) e).limit(10).asDoubleStream()));
197     }
198 
199     @Test
testDoubleOpsShortCircuit()200     public void testDoubleOpsShortCircuit() {
201         AtomicInteger count = new AtomicInteger();
202         DoubleStream.of(0).flatMap(i -> IntStream.range(0, 100).asDoubleStream()).
203                 peek(i -> count.incrementAndGet()).
204                 limit(10).toArray();
205         assertEquals(count.get(), 10);
206 
207         count.set(0);
208         Stream.of(0).flatMapToDouble(i -> IntStream.range(0, 100).asDoubleStream()).
209                 peek(i -> count.incrementAndGet()).
210                 limit(10).toArray();
211         assertEquals(count.get(), 10);
212     }
213 }
214