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