1 /*
2  * Copyright (c) 2014, 2021, 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 Tests counting of streams
27  * @bug 8031187 8067969 8075307 8265029
28  */
29 
30 package org.openjdk.tests.java.util.stream;
31 
32 import java.util.HashSet;
33 import java.util.concurrent.atomic.AtomicInteger;
34 import java.util.function.Supplier;
35 import java.util.stream.Collectors;
36 import java.util.stream.DoubleStream;
37 import java.util.stream.DoubleStreamTestDataProvider;
38 import java.util.stream.IntStream;
39 import java.util.stream.IntStreamTestDataProvider;
40 import java.util.stream.LongStream;
41 import java.util.stream.LongStreamTestDataProvider;
42 import java.util.stream.OpTestCase;
43 import java.util.stream.Stream;
44 import java.util.stream.StreamTestDataProvider;
45 import java.util.stream.TestData;
46 
47 import org.testng.annotations.Test;
48 
49 public class CountTest extends OpTestCase {
50 
51     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
testOps(String name, TestData.OfRef<Integer> data)52     public void testOps(String name, TestData.OfRef<Integer> data) {
53         long expectedCount = data.size();
54 
55         withData(data).
56                 terminal(Stream::count).
57                 expectedResult(expectedCount).
58                 exercise();
59 
60         withData(data).
61                 terminal(s -> s.skip(1), Stream::count).
62                 expectedResult(Math.max(0, expectedCount - 1)).
63                 exercise();
64 
65         // Test with an unknown sized stream
66         withData(data).
67                 terminal(s -> s.filter(e -> true), Stream::count).
68                 expectedResult(expectedCount).
69                 exercise();
70 
71         // Test counting collector
72         withData(data).
73                 terminal(s -> s, s -> s.collect(Collectors.counting())).
74                 expectedResult(expectedCount).
75                 exercise();
76 
77         // Test with stateful distinct op that is a barrier or lazy
78         // depending if source is not already distinct and encounter order is
79         // preserved or not
80         expectedCount = data.into(new HashSet<>()).size();
81         withData(data).
82                 terminal(Stream::distinct, Stream::count).
83                 expectedResult(expectedCount).
84                 exercise();
85         withData(data).
86                 terminal(s -> s.unordered().distinct(), Stream::count).
87                 expectedResult(expectedCount).
88                 exercise();
89     }
90 
91     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
testOps(String name, TestData.OfInt data)92     public void testOps(String name, TestData.OfInt data) {
93         long expectedCount = data.size();
94 
95         withData(data).
96                 terminal(IntStream::count).
97                 expectedResult(expectedCount).
98                 exercise();
99 
100         withData(data).
101             terminal(s -> s.skip(1), IntStream::count).
102             expectedResult(Math.max(0, expectedCount - 1)).
103             exercise();
104 
105         withData(data).
106                 terminal(s -> s.filter(e -> true), IntStream::count).
107                 expectedResult(expectedCount).
108                 exercise();
109 
110         expectedCount = data.into(new HashSet<>()).size();
111         withData(data).
112                 terminal(IntStream::distinct, IntStream::count).
113                 expectedResult(expectedCount).
114                 exercise();
115         withData(data).
116                 terminal(s -> s.unordered().distinct(), IntStream::count).
117                 expectedResult(expectedCount).
118                 exercise();
119     }
120 
121     @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
testOps(String name, TestData.OfLong data)122     public void testOps(String name, TestData.OfLong data) {
123         long expectedCount = data.size();
124 
125         withData(data).
126                 terminal(LongStream::count).
127                 expectedResult(expectedCount).
128                 exercise();
129 
130         withData(data).
131             terminal(s -> s.skip(1), LongStream::count).
132             expectedResult(Math.max(0, expectedCount - 1)).
133             exercise();
134 
135         withData(data).
136                 terminal(s -> s.filter(e -> true), LongStream::count).
137                 expectedResult(expectedCount).
138                 exercise();
139 
140         expectedCount = data.into(new HashSet<>()).size();
141         withData(data).
142                 terminal(LongStream::distinct, LongStream::count).
143                 expectedResult(expectedCount).
144                 exercise();
145         withData(data).
146                 terminal(s -> s.unordered().distinct(), LongStream::count).
147                 expectedResult(expectedCount).
148                 exercise();
149     }
150 
151     @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
testOps(String name, TestData.OfDouble data)152     public void testOps(String name, TestData.OfDouble data) {
153         long expectedCount = data.size();
154 
155         withData(data).
156                 terminal(DoubleStream::count).
157                 expectedResult(expectedCount).
158                 exercise();
159 
160         withData(data).
161             terminal(s -> s.skip(1), DoubleStream::count).
162             expectedResult(Math.max(0, expectedCount - 1)).
163             exercise();
164 
165         withData(data).
166                 terminal(s -> s.filter(e -> true), DoubleStream::count).
167                 expectedResult(expectedCount).
168                 exercise();
169 
170         expectedCount = data.into(new HashSet<>()).size();
171         withData(data).
172                 terminal(DoubleStream::distinct, DoubleStream::count).
173                 expectedResult(expectedCount).
174                 exercise();
175         withData(data).
176                 terminal(s -> s.unordered().distinct(), DoubleStream::count).
177                 expectedResult(expectedCount).
178                 exercise();
179     }
180 
181     @Test
testNoEvaluationForSizedStream()182     public void testNoEvaluationForSizedStream() {
183         checkStreamDoesNotConsumeElements(() -> Stream.of(1, 2, 3, 4), 4);
184         checkStreamDoesNotConsumeElements(() -> Stream.of(1, 2, 3, 4).skip(1).limit(2).skip(1), 1);
185         checkIntStreamDoesNotConsumeElements(() -> IntStream.of(1, 2, 3, 4), 4);
186         checkIntStreamDoesNotConsumeElements(() -> IntStream.of(1, 2, 3, 4).skip(1).limit(2).skip(1), 1);
187         checkLongStreamDoesNotConsumeElements(() -> LongStream.of(1, 2, 3, 4), 4);
188         checkLongStreamDoesNotConsumeElements(() -> LongStream.of(1, 2, 3, 4).skip(1).limit(2).skip(1), 1);
189         checkDoubleStreamDoesNotConsumeElements(() -> DoubleStream.of(1, 2, 3, 4), 4);
190         checkDoubleStreamDoesNotConsumeElements(() -> DoubleStream.of(1, 2, 3, 4).skip(1).limit(2).skip(1), 1);
191     }
192 
checkStreamDoesNotConsumeElements(Supplier<Stream<?>> supplier, long expectedCount)193     private void checkStreamDoesNotConsumeElements(Supplier<Stream<?>> supplier, long expectedCount) {
194         AtomicInteger ai = new AtomicInteger();
195         assertEquals(supplier.get().peek(e -> ai.getAndIncrement()).count(), expectedCount);
196         assertEquals(ai.get(), 0);
197 
198         assertEquals(supplier.get().peek(e -> ai.getAndIncrement()).parallel().count(), expectedCount);
199         assertEquals(ai.get(), 0);
200     }
201 
checkIntStreamDoesNotConsumeElements(Supplier<IntStream> supplier, long expectedCount)202     private void checkIntStreamDoesNotConsumeElements(Supplier<IntStream> supplier, long expectedCount) {
203         AtomicInteger ai = new AtomicInteger();
204         assertEquals(supplier.get().peek(e -> ai.getAndIncrement()).count(), expectedCount);
205         assertEquals(ai.get(), 0);
206 
207         assertEquals(supplier.get().peek(e -> ai.getAndIncrement()).parallel().count(), expectedCount);
208         assertEquals(ai.get(), 0);
209     }
210 
checkLongStreamDoesNotConsumeElements(Supplier<LongStream> supplier, long expectedCount)211     private void checkLongStreamDoesNotConsumeElements(Supplier<LongStream> supplier, long expectedCount) {
212         AtomicInteger ai = new AtomicInteger();
213         assertEquals(supplier.get().peek(e -> ai.getAndIncrement()).count(), expectedCount);
214         assertEquals(ai.get(), 0);
215 
216         assertEquals(supplier.get().peek(e -> ai.getAndIncrement()).parallel().count(), expectedCount);
217         assertEquals(ai.get(), 0);
218     }
219 
checkDoubleStreamDoesNotConsumeElements(Supplier<DoubleStream> supplier, long expectedCount)220     private void checkDoubleStreamDoesNotConsumeElements(Supplier<DoubleStream> supplier, long expectedCount) {
221         AtomicInteger ai = new AtomicInteger();
222         assertEquals(supplier.get().peek(e -> ai.getAndIncrement()).count(), expectedCount);
223         assertEquals(ai.get(), 0);
224 
225         assertEquals(supplier.get().peek(e -> ai.getAndIncrement()).parallel().count(), expectedCount);
226         assertEquals(ai.get(), 0);
227     }
228 }
229