1 /* 2 * Copyright (c) 2013, 2024, 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 * @bug 8020156 8020009 8022326 8012913 8024405 8024408 8071477 8336672 27 * @run testng SpliteratorCharacteristics 28 */ 29 30 import org.testng.annotations.Test; 31 32 import java.util.Arrays; 33 import java.util.Collection; 34 import java.util.Comparator; 35 import java.util.HashMap; 36 import java.util.HashSet; 37 import java.util.LinkedHashMap; 38 import java.util.LinkedHashSet; 39 import java.util.List; 40 import java.util.Map; 41 import java.util.PrimitiveIterator; 42 import java.util.Set; 43 import java.util.SortedMap; 44 import java.util.SortedSet; 45 import java.util.Spliterator; 46 import java.util.Spliterators; 47 import java.util.TreeMap; 48 import java.util.TreeSet; 49 import java.util.WeakHashMap; 50 import java.util.concurrent.ConcurrentSkipListMap; 51 import java.util.concurrent.ConcurrentSkipListSet; 52 import java.util.function.Supplier; 53 import java.util.stream.DoubleStream; 54 import java.util.stream.IntStream; 55 import java.util.stream.LongStream; 56 57 import static org.testng.Assert.*; 58 59 @Test 60 public class SpliteratorCharacteristics { 61 62 public void testSpliteratorFromCharSequence() { 63 class CharSequenceImpl implements CharSequence { 64 final String s; 65 66 public CharSequenceImpl(String s) { 67 this.s = s; 68 } 69 70 @Override 71 public int length() { 72 return s.length(); 73 } 74 75 @Override 76 public char charAt(int index) { 77 return s.charAt(index); 78 } 79 80 @Override 81 public CharSequence subSequence(int start, int end) { 82 return s.subSequence(start, end); 83 } 84 85 @Override 86 public String toString() { 87 return s; 88 } 89 } 90 91 CharSequence cs = "A"; 92 Spliterator.OfInt s = cs.chars().spliterator(); 93 assertCharacteristics(s, Spliterator.IMMUTABLE | Spliterator.ORDERED | 94 Spliterator.SIZED | Spliterator.SUBSIZED); 95 assertHasNotCharacteristics(s, Spliterator.CONCURRENT); 96 s = cs.codePoints().spliterator(); 97 assertCharacteristics(s, Spliterator.IMMUTABLE | Spliterator.ORDERED); 98 assertHasNotCharacteristics(s, Spliterator.CONCURRENT); 99 100 for (CharSequence c : Arrays.asList(new CharSequenceImpl("A"), 101 new StringBuilder("A"), 102 new StringBuffer("A"))) { 103 s = cs.chars().spliterator(); 104 assertCharacteristics(s, Spliterator.ORDERED | 105 Spliterator.SIZED | Spliterator.SUBSIZED); 106 assertHasNotCharacteristics(s, Spliterator.CONCURRENT); 107 s = cs.codePoints().spliterator(); 108 assertCharacteristics(s, Spliterator.ORDERED); 109 assertHasNotCharacteristics(s, Spliterator.CONCURRENT); 110 } 111 } 112 113 public void testSpliteratorFromCollection() { 114 List<String> l = Arrays.asList("A", "B", "C", "D"); 115 116 { 117 Spliterator<?> s = Spliterators.spliterator(l, 0); 118 assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); 119 assertHasNotCharacteristics(s, Spliterator.CONCURRENT); 120 } 121 122 { 123 Spliterator<?> s = Spliterators.spliterator(l, Spliterator.CONCURRENT); 124 assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); 125 assertCharacteristics(s, Spliterator.CONCURRENT); 126 } 127 128 { 129 Spliterator<?> s = Spliterators.spliterator(l.iterator(), 1, 0); 130 assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); 131 assertHasNotCharacteristics(s, Spliterator.CONCURRENT); 132 } 133 134 { 135 Spliterator<?> s = Spliterators.spliterator(l.iterator(), 1, Spliterator.CONCURRENT); 136 assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); 137 assertCharacteristics(s, Spliterator.CONCURRENT); 138 } 139 140 { 141 Spliterator<?> s = Spliterators.spliteratorUnknownSize(l.iterator(), 0); 142 assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); 143 } 144 145 { 146 Spliterator<?> s = Spliterators.spliteratorUnknownSize( 147 l.iterator(), Spliterator.SIZED | Spliterator.SUBSIZED); 148 assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); 149 } 150 } 151 152 public void testSpliteratorOfIntFromIterator() { 153 Supplier<PrimitiveIterator.OfInt> si = () -> IntStream.of(1, 2, 3, 4).iterator(); 154 155 { 156 Spliterator<?> s = Spliterators.spliterator(si.get(), 1, 0); 157 assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); 158 assertHasNotCharacteristics(s, Spliterator.CONCURRENT); 159 } 160 161 { 162 Spliterator<?> s = Spliterators.spliterator(si.get(), 1, Spliterator.CONCURRENT); 163 assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); 164 assertCharacteristics(s, Spliterator.CONCURRENT); 165 } 166 167 { 168 Spliterator<?> s = Spliterators.spliteratorUnknownSize(si.get(), 0); 169 assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); 170 } 171 172 { 173 Spliterator<?> s = Spliterators.spliteratorUnknownSize( 174 si.get(), Spliterator.SIZED | Spliterator.SUBSIZED); 175 assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); 176 } 177 } 178 179 public void testSpliteratorOfLongFromIterator() { 180 Supplier<PrimitiveIterator.OfLong> si = () -> LongStream.of(1, 2, 3, 4).iterator(); 181 182 { 183 Spliterator<?> s = Spliterators.spliterator(si.get(), 1, 0); 184 assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); 185 assertHasNotCharacteristics(s, Spliterator.CONCURRENT); 186 } 187 188 { 189 Spliterator<?> s = Spliterators.spliterator(si.get(), 1, Spliterator.CONCURRENT); 190 assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); 191 assertCharacteristics(s, Spliterator.CONCURRENT); 192 } 193 194 { 195 Spliterator<?> s = Spliterators.spliteratorUnknownSize(si.get(), 0); 196 assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); 197 } 198 199 { 200 Spliterator<?> s = Spliterators.spliteratorUnknownSize( 201 si.get(), Spliterator.SIZED | Spliterator.SUBSIZED); 202 assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); 203 } 204 } 205 206 public void testSpliteratorOfDoubleFromIterator() { 207 Supplier<PrimitiveIterator.OfDouble> si = () -> DoubleStream.of(1, 2, 3, 4).iterator(); 208 209 { 210 Spliterator<?> s = Spliterators.spliterator(si.get(), 1, 0); 211 assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); 212 assertHasNotCharacteristics(s, Spliterator.CONCURRENT); 213 } 214 215 { 216 Spliterator<?> s = Spliterators.spliterator(si.get(), 1, Spliterator.CONCURRENT); 217 assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); 218 assertCharacteristics(s, Spliterator.CONCURRENT); 219 } 220 221 { 222 Spliterator<?> s = Spliterators.spliteratorUnknownSize(si.get(), 0); 223 assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); 224 } 225 226 { 227 Spliterator<?> s = Spliterators.spliteratorUnknownSize( 228 si.get(), Spliterator.SIZED | Spliterator.SUBSIZED); 229 assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); 230 } 231 } 232 233 // 234 235 public void testHashMap() { 236 assertMapCharacteristics(new HashMap<>(), 237 Spliterator.SIZED | Spliterator.DISTINCT); 238 } 239 240 public void testWeakHashMap() { 241 assertMapCharacteristics(new WeakHashMap<>(), 242 Spliterator.DISTINCT); 243 } 244 245 public void testHashSet() { 246 assertSetCharacteristics(new HashSet<>(), 247 Spliterator.SIZED | Spliterator.DISTINCT); 248 } 249 250 public void testLinkedHashMap() { 251 assertMapCharacteristics(new LinkedHashMap<>(), 252 Spliterator.SIZED | Spliterator.DISTINCT | 253 Spliterator.ORDERED); 254 } 255 256 public void testLinkedHashSet() { 257 assertSetCharacteristics(new LinkedHashSet<>(), 258 Spliterator.SIZED | Spliterator.DISTINCT | 259 Spliterator.ORDERED); 260 } 261 262 public void testTreeMap() { 263 assertSortedMapCharacteristics(new TreeMap<>(), 264 Spliterator.SIZED | Spliterator.DISTINCT | 265 Spliterator.SORTED | Spliterator.ORDERED); 266 } 267 268 public void testTreeMapWithComparator() { 269 assertSortedMapCharacteristics(new TreeMap<>(Comparator.reverseOrder()), 270 Spliterator.SIZED | Spliterator.DISTINCT | 271 Spliterator.SORTED | Spliterator.ORDERED); 272 } 273 274 public void testTreeSet() { 275 assertSortedSetCharacteristics(new TreeSet<>(), 276 Spliterator.SIZED | Spliterator.DISTINCT | 277 Spliterator.SORTED | Spliterator.ORDERED); 278 } 279 280 public void testTreeSetWithComparator() { 281 assertSortedSetCharacteristics(new TreeSet<>(Comparator.reverseOrder()), 282 Spliterator.SIZED | Spliterator.DISTINCT | 283 Spliterator.SORTED | Spliterator.ORDERED); 284 } 285 286 public void testConcurrentSkipListMap() { 287 assertSortedMapCharacteristics(new ConcurrentSkipListMap<>(), 288 Spliterator.CONCURRENT | Spliterator.NONNULL | 289 Spliterator.DISTINCT | Spliterator.SORTED | 290 Spliterator.ORDERED); 291 } 292 293 public void testConcurrentSkipListMapWithComparator() { 294 assertSortedMapCharacteristics(new ConcurrentSkipListMap<>(Comparator.<String>reverseOrder()), 295 Spliterator.CONCURRENT | Spliterator.NONNULL | 296 Spliterator.DISTINCT | Spliterator.SORTED | 297 Spliterator.ORDERED); 298 } 299 300 public void testConcurrentSkipListSet() { 301 assertSortedSetCharacteristics(new ConcurrentSkipListSet<>(), 302 Spliterator.CONCURRENT | Spliterator.NONNULL | 303 Spliterator.DISTINCT | Spliterator.SORTED | 304 Spliterator.ORDERED); 305 } 306 307 public void testConcurrentSkipListSetWithComparator() { 308 assertSortedSetCharacteristics(new ConcurrentSkipListSet<>(Comparator.reverseOrder()), 309 Spliterator.CONCURRENT | Spliterator.NONNULL | 310 Spliterator.DISTINCT | Spliterator.SORTED | 311 Spliterator.ORDERED); 312 } 313 314 315 // 316 317 318 void assertMapCharacteristics(Map<String, String> m, int keyCharacteristics) { 319 assertMapCharacteristics(m, keyCharacteristics, 0); 320 } 321 322 void assertMapCharacteristics(Map<String, String> m, int keyCharacteristics, int notValueCharacteristics) { 323 initMap(m); 324 325 assertCharacteristics(m.keySet(), keyCharacteristics); 326 327 assertCharacteristics(m.values(), 328 keyCharacteristics & ~(Spliterator.DISTINCT | notValueCharacteristics)); 329 330 assertCharacteristics(m.entrySet(), keyCharacteristics); 331 332 if ((keyCharacteristics & Spliterator.SORTED) == 0) { 333 assertISEComparator(m.keySet()); 334 assertISEComparator(m.values()); 335 assertISEComparator(m.entrySet()); 336 } 337 } 338 339 void assertSetCharacteristics(Set<String> s, int keyCharacteristics) { 340 initSet(s); 341 342 assertCharacteristics(s, keyCharacteristics); 343 344 if ((keyCharacteristics & Spliterator.SORTED) == 0) { 345 assertISEComparator(s); 346 } 347 } 348 349 void assertSortedMapCharacteristics(SortedMap<String, String> m, int keyCharacteristics) { 350 assertMapCharacteristics(m, keyCharacteristics, Spliterator.SORTED); 351 352 Set<String> keys = m.keySet(); 353 if (m.comparator() != null) { 354 assertNotNullComparator(keys); 355 } 356 else { 357 assertNullComparator(keys); 358 } 359 360 assertISEComparator(m.values()); 361 362 assertNotNullComparator(m.entrySet()); 363 } 364 365 void assertSortedSetCharacteristics(SortedSet<String> s, int keyCharacteristics) { 366 assertSetCharacteristics(s, keyCharacteristics); 367 368 if (s.comparator() != null) { 369 assertNotNullComparator(s); 370 } 371 else { 372 assertNullComparator(s); 373 } 374 } 375 376 void initMap(Map<String, String> m) { 377 m.put("A", "4"); 378 m.put("B", "3"); 379 m.put("C", "2"); 380 m.put("D", "1"); 381 } 382 383 void initSet(Set<String> s) { 384 s.addAll(Arrays.asList("A", "B", "C", "D")); 385 } 386 387 void assertCharacteristics(Collection<?> c, int expectedCharacteristics) { 388 assertCharacteristics(c.spliterator(), expectedCharacteristics); 389 } 390 391 void assertCharacteristics(Spliterator<?> s, int expectedCharacteristics) { 392 assertTrue(s.hasCharacteristics(expectedCharacteristics), 393 "Spliterator characteristics"); 394 } 395 396 void assertHasNotCharacteristics(Spliterator<?> s, int expectedCharacteristics) { 397 assertFalse(s.hasCharacteristics(expectedCharacteristics), 398 "Spliterator characteristics"); 399 } 400 401 void assertNullComparator(Collection<?> c) { 402 assertNull(c.spliterator().getComparator(), 403 "Comparator of Spliterator of Collection"); 404 } 405 406 void assertNotNullComparator(Collection<?> c) { 407 assertNotNull(c.spliterator().getComparator(), 408 "Comparator of Spliterator of Collection"); 409 } 410 411 void assertISEComparator(Collection<?> c) { 412 assertISEComparator(c.spliterator()); 413 } 414 415 void assertISEComparator(Spliterator<?> s) { 416 boolean caught = false; 417 try { 418 s.getComparator(); 419 } 420 catch (IllegalStateException e) { 421 caught = true; 422 } 423 assertTrue(caught, "Throwing IllegalStateException"); 424 } 425 }