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