1 /*
2  * Copyright (c) 2012, 2013, 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 org.testng.annotations.Test;
26 
27 import java.util.*;
28 import java.util.function.Function;
29 import java.util.stream.*;
30 
31 import static java.util.stream.LambdaTestHelpers.*;
32 import static org.testng.Assert.assertEquals;
33 
34 
35 /**
36  * ToArrayOpTest
37  *
38  */
39 @Test
40 public class ToArrayOpTest extends OpTestCase {
41 
testToArray()42     public void testToArray() {
43         assertCountSum(Arrays.asList(countTo(0).stream().toArray()), 0, 0);
44         assertCountSum(Arrays.asList(countTo(10).stream().toArray()), 10, 55);
45     }
46 
47     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
testOps(String name, TestData.OfRef<Integer> data)48     public void testOps(String name, TestData.OfRef<Integer> data) {
49         exerciseTerminalOps(data, s -> s.toArray());
50     }
51 
52     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
testOpsWithMap(String name, TestData.OfRef<Integer> data)53     public void testOpsWithMap(String name, TestData.OfRef<Integer> data) {
54         // Retain the size of the source
55         // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
56 
57         Object[] objects = exerciseTerminalOps(data, s -> s.map(i -> (Integer) (i + i)), s -> s.toArray());
58         assertTrue(objects.length == data.size());
59     }
60 
61     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
testOpsWithSorted(String name, TestData.OfRef<Integer> data)62     public void testOpsWithSorted(String name, TestData.OfRef<Integer> data) {
63         // Retain the size of the source
64         // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
65 
66         Object[] objects = exerciseTerminalOps(data, s -> s.sorted(), s -> s.toArray());
67         assertTrue(objects.length == data.size());
68     }
69 
70     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
testOpsWithFlatMap(String name, TestData.OfRef<Integer> data)71     public void testOpsWithFlatMap(String name, TestData.OfRef<Integer> data) {
72         // Double the size of the source
73         // Fixed size optimizations will not be used
74 
75         Object[] objects = exerciseTerminalOps(data,
76                                                s -> s.flatMap(e -> Arrays.stream(new Object[] { e, e })),
77                                                s -> s.toArray());
78         assertTrue(objects.length == data.size() * 2);
79     }
80 
81     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
testOpsWithFilter(String name, TestData.OfRef<Integer> data)82     public void testOpsWithFilter(String name, TestData.OfRef<Integer> data) {
83         // Reduce the size of the source
84         // Fixed size optimizations will not be used
85 
86         exerciseTerminalOps(data, s -> s.filter(LambdaTestHelpers.pEven), s -> s.toArray());
87     }
88 
testAsArrayWithType()89     public void testAsArrayWithType() {
90         exerciseTerminalOps(
91                 TestData.Factory.ofCollection("", Arrays.asList(1.1, 2.2, 3.4, 4.4)),
92                 s -> // First pipeline slice using Object[] with Double elements
93                     s.sorted()
94                     // Second pipeline slice using Integer[] with Integer elements
95                     .map((Double d) -> Integer.valueOf(d.intValue())).sorted(),
96                 s -> s.toArray(Integer[]::new));
97     }
98 
99     private List<Function<Stream<Integer>, Stream<Integer>>> uniqueAndSortedPermutations =
100             LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
101                     s -> s.distinct(),
102                     s -> s.distinct(),
103                     s -> s.sorted(),
104                     s -> s.sorted()
105             ));
106 
107     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
testDistinctAndSortedPermutations(String name, TestData.OfRef<Integer> data)108     public void testDistinctAndSortedPermutations(String name, TestData.OfRef<Integer> data) {
109         for (Function<Stream<Integer>, Stream<Integer>> f : uniqueAndSortedPermutations) {
110             exerciseTerminalOps(data, f, s -> s.toArray());
111 
112             Integer[] is = exerciseTerminalOps(data, f, s -> s.toArray(Integer[]::new));
113             assertEquals(is.getClass(), Integer[].class);
114 
115             Number[] ns = exerciseTerminalOps(data, f, s -> s.toArray(Number[]::new));
116             assertEquals(ns.getClass(), Number[].class);
117 
118             if (data.size() > 0) {
119                 Exception caught = null;
120                 try {
121                     exerciseTerminalOps(data, f, s -> s.toArray(String[]::new));
122                 } catch (Exception e) {
123                     caught = e;
124                 }
125                 assertTrue(caught != null);
126                 assertEquals(caught.getClass(), ArrayStoreException.class);
127             }
128         }
129     }
130 
131     private List<Function<Stream<Integer>, Stream<Integer>>> statefulOpPermutations =
132             LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
133                     s -> s.limit(10),
134                     s -> s.distinct(),
135                     s -> s.sorted()
136             ));
137 
statefulOpResultAsserter(TestData.OfRef<Integer> data)138     private <T extends Object> ResultAsserter<T[]> statefulOpResultAsserter(TestData.OfRef<Integer> data) {
139         return (act, exp, ord, par) -> {
140             if (par) {
141                 if (!data.isOrdered()) {
142                     // Relax the checking if the data source is unordered
143                     // It is not exactly possible to determine if the limit
144                     // operation is present and if it is before or after
145                     // the sorted operation
146                     // If the limit operation is present and before the sorted
147                     // operation then the sub-set output after limit is a
148                     // non-deterministic sub-set of the source
149                     List<Integer> expected = new ArrayList<>();
150                     data.forEach(expected::add);
151 
152                     List<T> actual = Arrays.asList(act);
153 
154                     assertEquals(actual.size(), exp.length);
155                     assertTrue(expected.containsAll(actual));
156                     return;
157                 }
158                 else if (!ord) {
159                     LambdaTestHelpers.assertContentsUnordered(Arrays.asList(act),
160                                                               Arrays.asList(exp));
161                     return;
162                 }
163             }
164             assertEquals(act, exp);
165         };
166     }
167 
168     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class,
169           groups = { "serialization-hostile" })
170     public void testStatefulOpPermutations(String name, TestData.OfRef<Integer> data) {
171         for (Function<Stream<Integer>, Stream<Integer>> f : statefulOpPermutations) {
172             withData(data).terminal(f, s -> s.toArray())
173                     .resultAsserter(statefulOpResultAsserter(data))
174                     .exercise();
175 
176             Integer[] is = withData(data).terminal(f, s -> s.toArray(Integer[]::new))
177                     .resultAsserter(statefulOpResultAsserter(data))
178                     .exercise();
179             assertEquals(is.getClass(), Integer[].class);
180 
181             Number[] ns = withData(data).terminal(f, s -> s.toArray(Number[]::new))
182                     .resultAsserter(statefulOpResultAsserter(data))
183                     .exercise();
184             assertEquals(ns.getClass(), Number[].class);
185 
186             if (data.size() > 0) {
187                 Exception caught = null;
188                 try {
189                     exerciseTerminalOps(data, f, s -> s.toArray(String[]::new));
190                 } catch (Exception e) {
191                     caught = e;
192                 }
193                 assertTrue(caught != null);
194                 assertEquals(caught.getClass(), ArrayStoreException.class);
195             }
196         }
197     }
198 
199     //
200 
201     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
202     public void testIntOps(String name, TestData.OfInt data) {
203         exerciseTerminalOps(data, s -> s.toArray());
204     }
205 
206     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
207     public void testIntOpsWithMap(String name, TestData.OfInt data) {
208         // Retain the size of the source
209         // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
210 
211         int[] ints = exerciseTerminalOps(data, s -> s.map(i -> i + i), s -> s.toArray());
212         assertTrue(ints.length == data.size());
213     }
214 
215     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
216     public void testIntOpsWithSorted(String name, TestData.OfInt data) {
217         // Retain the size of the source
218         // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
219 
220         int[] ints = exerciseTerminalOps(data, s -> s.sorted(), (IntStream s) -> s.toArray());
221         assertTrue(ints.length == data.size());
222     }
223 
224     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
225     public void testIntOpsWithFlatMap(String name, TestData.OfInt data) {
226         // Int the size of the source
227         // Fixed size optimizations will not be used
228 
229         int[] objects = exerciseTerminalOps(data,
230                                                s -> s.flatMap(e -> Arrays.stream(new int[] { e, e })),
231                                                s -> s.toArray());
232         assertTrue(objects.length == data.size() * 2);
233     }
234 
235     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
236     public void testIntOpsWithFilter(String name, TestData.OfInt data) {
237         // Reduce the size of the source
238         // Fixed size optimizations will not be used
239 
240         exerciseTerminalOps(data, s -> s.filter(LambdaTestHelpers.ipEven), s -> s.toArray());
241     }
242 
243     private List<Function<IntStream, IntStream>> intUniqueAndSortedPermutations =
244             LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
245                     s -> s.distinct(),
246                     s -> s.distinct(),
247                     s -> s.sorted(),
248                     s -> s.sorted()
249             ));
250 
251     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
252     public void testIntDistinctAndSortedPermutations(String name, TestData.OfInt data) {
253         for (Function<IntStream, IntStream> f : intUniqueAndSortedPermutations) {
254             exerciseTerminalOps(data, f, s -> s.toArray());
255         }
256     }
257 
258     private List<Function<IntStream, IntStream>> intStatefulOpPermutations =
259             LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
260                     s -> s.limit(10),
261                     s -> s.distinct(),
262                     s -> s.sorted()
263             ));
264 
265     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
266     public void testIntStatefulOpPermutations(String name, TestData.OfInt data) {
267         for (Function<IntStream, IntStream> f : intStatefulOpPermutations) {
268             exerciseTerminalOps(data, f, s -> s.toArray());
269         }
270     }
271 
272     //
273 
274     @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
275     public void testLongOps(String name, TestData.OfLong data) {
276         exerciseTerminalOps(data, s -> s.toArray());
277     }
278 
279     @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
280     public void testLongOpsWithMap(String name, TestData.OfLong data) {
281         // Retain the size of the source
282         // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
283 
284         long[] longs = exerciseTerminalOps(data, s -> s.map(i -> i + i), s -> s.toArray());
285         assertTrue(longs.length == data.size());
286     }
287 
288     @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
289     public void testLongOpsWithSorted(String name, TestData.OfLong data) {
290         // Retain the size of the source
291         // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
292 
293         long[] longs = exerciseTerminalOps(data, s -> s.sorted(), (LongStream s) -> s.toArray());
294         assertTrue(longs.length == data.size());
295     }
296 
297     @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
298     public void testLongOpsWithFlatMap(String name, TestData.OfLong data) {
299         // Long the size of the source
300         // Fixed size optimizations will not be used
301 
302         long[] objects = exerciseTerminalOps(data,
303                                                s -> s.flatMap(e -> Arrays.stream(new long[] { e, e })),
304                                                s -> s.toArray());
305         assertTrue(objects.length == data.size() * 2);
306     }
307 
308     @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
309     public void testLongOpsWithFilter(String name, TestData.OfLong data) {
310         // Reduce the size of the source
311         // Fixed size optimizations will not be used
312 
313         exerciseTerminalOps(data, s -> s.filter(LambdaTestHelpers.lpEven), s -> s.toArray());
314     }
315 
316     private List<Function<LongStream, LongStream>> longUniqueAndSortedPermutations =
317             LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
318                     s -> s.distinct(),
319                     s -> s.distinct(),
320                     s -> s.sorted(),
321                     s -> s.sorted()
322             ));
323 
324     @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
325     public void testLongDistinctAndSortedPermutations(String name, TestData.OfLong data) {
326         for (Function<LongStream, LongStream> f : longUniqueAndSortedPermutations) {
327             exerciseTerminalOps(data, f, s -> s.toArray());
328         }
329     }
330 
331     private List<Function<LongStream, LongStream>> longStatefulOpPermutations =
332             LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
333                     s -> s.limit(10),
334                     s -> s.distinct(),
335                     s -> s.sorted()
336             ));
337 
338     @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
339     public void testLongStatefulOpPermutations(String name, TestData.OfLong data) {
340         for (Function<LongStream, LongStream> f : longStatefulOpPermutations) {
341             exerciseTerminalOps(data, f, s -> s.toArray());
342         }
343     }
344 
345     //
346 
347     @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
348     public void testDoubleOps(String name, TestData.OfDouble data) {
349         exerciseTerminalOps(data, s -> s.toArray());
350     }
351 
352     @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
353     public void testDoubleOpsWithMap(String name, TestData.OfDouble data) {
354         // Retain the size of the source
355         // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
356 
357         double[] doubles = exerciseTerminalOps(data, s -> s.map(i -> i + i), s -> s.toArray());
358         assertTrue(doubles.length == data.size());
359     }
360 
361     @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
362     public void testDoubleOpsWithSorted(String name, TestData.OfDouble data) {
363         // Retain the size of the source
364         // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
365 
366         double[] doubles = exerciseTerminalOps(data, s -> s.sorted(), (DoubleStream s) -> s.toArray());
367         assertTrue(doubles.length == data.size());
368     }
369 
370     @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
371     public void testDoubleOpsWithFlatMap(String name, TestData.OfDouble data) {
372         // Double the size of the source
373         // Fixed size optimizations will not be used
374 
375         double[] objects = exerciseTerminalOps(data,
376                                                s -> s.flatMap(e -> Arrays.stream(new double[] { e, e })),
377                                                s -> s.toArray());
378         assertTrue(objects.length == data.size() * 2);
379     }
380 
381     @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
382     public void testDoubleOpsWithFilter(String name, TestData.OfDouble data) {
383         // Reduce the size of the source
384         // Fixed size optimizations will not be used
385 
386         exerciseTerminalOps(data, s -> s.filter(LambdaTestHelpers.dpEven), s -> s.toArray());
387     }
388 
389     private List<Function<DoubleStream, DoubleStream>> doubleUniqueAndSortedPermutations =
390             LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
391                     s -> s.distinct(),
392                     s -> s.distinct(),
393                     s -> s.sorted(),
394                     s -> s.sorted()
395             ));
396 
397     @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
398     public void testDoubleDistinctAndSortedPermutations(String name, TestData.OfDouble data) {
399         for (Function<DoubleStream, DoubleStream> f : doubleUniqueAndSortedPermutations) {
400             exerciseTerminalOps(data, f, s -> s.toArray());
401         }
402     }
403 
404     private List<Function<DoubleStream, DoubleStream>> doubleStatefulOpPermutations =
405             LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
406                     s -> s.limit(10),
407                     s -> s.distinct(),
408                     s -> s.sorted()
409             ));
410 
411     @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
412     public void testDoubleStatefulOpPermutations(String name, TestData.OfDouble data) {
413         for (Function<DoubleStream, DoubleStream> f : doubleStatefulOpPermutations) {
414             exerciseTerminalOps(data, f, s -> s.toArray());
415         }
416     }
417 }
418