1 /*
   2  * Copyright (c) 2013, 2026, 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 Spliterator traversing and splitting tests
  27  * @library /lib/testlibrary/bootlib
  28  * @modules java.base/jdk.internal.misc
  29  * @build java.base/java.util.SpliteratorOfIntDataBuilder
  30  *        java.base/java.util.SpliteratorTestHelper
  31  * @run testng SpliteratorTraversingAndSplittingTest
  32  * @run testng/othervm --enable-preview SpliteratorTraversingAndSplittingTest
  33  * @bug 8020016 8071477 8072784 8169838 8336672
  34  */
  35 
  36 import jdk.internal.misc.PreviewFeatures;
  37 
  38 import org.testng.annotations.DataProvider;
  39 import org.testng.annotations.Test;
  40 
  41 import java.nio.CharBuffer;
  42 import java.util.AbstractCollection;
  43 import java.util.AbstractList;
  44 import java.util.AbstractSet;
  45 import java.util.ArrayDeque;
  46 import java.util.ArrayList;
  47 import java.util.Arrays;
  48 import java.util.Collection;
  49 import java.util.Collections;
  50 import java.util.Comparator;
  51 import java.util.HashMap;
  52 import java.util.HashSet;
  53 import java.util.IdentityHashMap;
  54 import java.util.Iterator;
  55 import java.util.LinkedHashMap;
  56 import java.util.LinkedHashSet;
  57 import java.util.LinkedList;
  58 import java.util.List;
  59 import java.util.ListIterator;
  60 import java.util.Map;
  61 import java.util.PriorityQueue;
  62 import java.util.RandomAccess;
  63 import java.util.Set;
  64 import java.util.SortedSet;
  65 import java.util.Spliterator;
  66 import java.util.SpliteratorOfIntDataBuilder;
  67 import java.util.SpliteratorTestHelper;
  68 import java.util.Spliterators;
  69 import java.util.Stack;
  70 import java.util.TreeMap;
  71 import java.util.TreeSet;
  72 import java.util.Vector;
  73 import java.util.WeakHashMap;
  74 import java.util.concurrent.ArrayBlockingQueue;
  75 import java.util.concurrent.ConcurrentHashMap;
  76 import java.util.concurrent.ConcurrentLinkedQueue;
  77 import java.util.concurrent.ConcurrentSkipListMap;
  78 import java.util.concurrent.ConcurrentSkipListSet;
  79 import java.util.concurrent.CopyOnWriteArrayList;
  80 import java.util.concurrent.CopyOnWriteArraySet;
  81 import java.util.concurrent.LinkedBlockingDeque;
  82 import java.util.concurrent.LinkedBlockingQueue;
  83 import java.util.concurrent.LinkedTransferQueue;
  84 import java.util.concurrent.PriorityBlockingQueue;
  85 import java.util.function.Consumer;
  86 import java.util.function.DoubleConsumer;
  87 import java.util.function.Function;
  88 import java.util.function.IntConsumer;
  89 import java.util.function.LongConsumer;
  90 import java.util.function.Supplier;
  91 import java.util.function.UnaryOperator;
  92 
  93 public class SpliteratorTraversingAndSplittingTest extends SpliteratorTestHelper {
  94 
  95     private static final List<Integer> SIZES = Arrays.asList(0, 1, 10, 42);
  96 
  97     private static final String LOW = new String(new char[] {Character.MIN_LOW_SURROGATE});
  98     private static final String HIGH = new String(new char[] {Character.MIN_HIGH_SURROGATE});
  99     private static final String HIGH_LOW = HIGH + LOW;
 100     private static final String CHAR_HIGH_LOW = "A" + HIGH_LOW;
 101     private static final String HIGH_LOW_CHAR = HIGH_LOW + "A";
 102     private static final String CHAR_HIGH_LOW_CHAR = "A" + HIGH_LOW + "A";
 103 
 104     private static final List<String> STRINGS = generateTestStrings();
 105 
 106     private static List<String> generateTestStrings() {
 107         List<String> strings = new ArrayList<>();
 108         for (int n : Arrays.asList(1, 2, 3, 16, 17)) {
 109             strings.add(generate("A", n));
 110             strings.add(generate(LOW, n));
 111             strings.add(generate(HIGH, n));
 112             strings.add(generate(HIGH_LOW, n));
 113             strings.add(generate(CHAR_HIGH_LOW, n));
 114             strings.add(generate(HIGH_LOW_CHAR, n));
 115             strings.add(generate(CHAR_HIGH_LOW_CHAR, n));
 116         }
 117         return strings;
 118     }
 119 
 120     private static String generate(String s, int n) {
 121         StringBuilder sb = new StringBuilder();
 122         for (int i = 0; i < n; i++) {
 123             sb.append(s);
 124         }
 125         return sb.toString();
 126     }
 127 
 128     private static class SpliteratorDataBuilder<T> {
 129         List<Object[]> data;
 130 
 131         List<T> exp;
 132 
 133         List<T> expRev;
 134 
 135         Map<T, T> mExp;
 136 
 137         Map<T, T> mExpRev;
 138 
 139         SpliteratorDataBuilder(List<Object[]> data, List<T> exp) {
 140             this.data = data;
 141             this.exp = exp;
 142             this.expRev = new ArrayList<>(exp);
 143             Collections.reverse(this.expRev);
 144             this.mExp = createMap(exp);
 145             this.mExpRev = createMap(expRev);
 146         }
 147 
 148         Map<T, T> createMap(List<T> l) {
 149             Map<T, T> m = new LinkedHashMap<>();
 150             for (T t : l) {
 151                 m.put(t, t);
 152             }
 153             return m;
 154         }
 155 
 156         void add(String description, Collection<?> expected, Supplier<Spliterator<?>> s) {
 157             description = joiner(description).toString();
 158             data.add(new Object[]{description, expected, s});
 159         }
 160 
 161         void add(String description, Supplier<Spliterator<?>> s) {
 162             add(description, exp, s);
 163         }
 164 
 165         void addCollection(Function<Collection<T>, ? extends Collection<T>> c) {
 166             add("new " + c.apply(Collections.<T>emptyList()).getClass().getName() + ".spliterator()",
 167                 () -> c.apply(exp).spliterator());
 168         }
 169 
 170         void addList(Function<Collection<T>, ? extends List<T>> l) {
 171             addCollection(l);
 172             addCollection(l.andThen(list -> list.subList(0, list.size())));
 173         }
 174 
 175         void addMap(Function<Map<T, T>, ? extends Map<T, T>> m) {
 176             String description = "new " + m.apply(Collections.<T, T>emptyMap()).getClass().getName();
 177             addMap(m, description);
 178         }
 179 
 180         void addDescendingMap(Function<Map<T, T>, ? extends Map<T, T>> m) {
 181             String description = "new " + m.apply(Collections.<T, T>emptyMap()).getClass().getName();
 182             addDescendingMap(m, description);
 183         }
 184 
 185         void addMap(Function<Map<T, T>, ? extends Map<T, T>> m, String description) {
 186             add(description + ".keySet().spliterator()", () -> m.apply(mExp).keySet().spliterator());
 187             add(description + ".values().spliterator()", () -> m.apply(mExp).values().spliterator());
 188             add(description + ".entrySet().spliterator()", mExp.entrySet(), () -> m.apply(mExp).entrySet().spliterator());
 189         }
 190 
 191         void addDescendingMap(Function<Map<T, T>, ? extends Map<T, T>> m, String description) {
 192             add(description + ".keySet().spliterator()", expRev, () -> m.apply(mExp).keySet().spliterator());
 193             add(description + ".values().spliterator()", expRev, () -> m.apply(mExp).values().spliterator());
 194             add(description + ".entrySet().spliterator()", mExpRev.entrySet(), () -> m.apply(mExp).entrySet().spliterator());
 195         }
 196 
 197         StringBuilder joiner(String description) {
 198             return new StringBuilder(description).
 199                     append(" {").
 200                     append("size=").append(exp.size()).
 201                     append("}");
 202         }
 203     }
 204 
 205     static Object[][] spliteratorDataProvider;
 206 
 207     @DataProvider(name = "Spliterator<Integer>")
 208     public static Object[][] spliteratorDataProvider() {
 209         if (spliteratorDataProvider != null) {
 210             return spliteratorDataProvider;
 211         }
 212 
 213         List<Object[]> data = new ArrayList<>();
 214         for (int size : SIZES) {
 215             List<Integer> exp = listIntRange(size);
 216             SpliteratorDataBuilder<Integer> db = new SpliteratorDataBuilder<>(data, exp);
 217 
 218             // Direct spliterator methods
 219 
 220             db.add("Spliterators.spliterator(Collection, ...)",
 221                    () -> Spliterators.spliterator(exp, 0));
 222 
 223             db.add("Spliterators.spliterator(Iterator, ...)",
 224                    () -> Spliterators.spliterator(exp.iterator(), exp.size(), 0));
 225 
 226             db.add("Spliterators.spliteratorUnknownSize(Iterator, ...)",
 227                    () -> Spliterators.spliteratorUnknownSize(exp.iterator(), 0));
 228 
 229             db.add("Spliterators.spliterator(Spliterators.iteratorFromSpliterator(Spliterator ), ...)",
 230                    () -> Spliterators.spliterator(Spliterators.iterator(exp.spliterator()), exp.size(), 0));
 231 
 232             db.add("Spliterators.spliterator(T[], ...)",
 233                    () -> Spliterators.spliterator(exp.toArray(new Integer[0]), 0));
 234 
 235             db.add("Arrays.spliterator(T[], ...)",
 236                    () -> Arrays.spliterator(exp.toArray(new Integer[0])));
 237 
 238             class SpliteratorFromIterator extends Spliterators.AbstractSpliterator<Integer> {
 239                 Iterator<Integer> it;
 240 
 241                 SpliteratorFromIterator(Iterator<Integer> it, long est) {
 242                     super(est, Spliterator.SIZED);
 243                     this.it = it;
 244                 }
 245 
 246                 @Override
 247                 public boolean tryAdvance(Consumer<? super Integer> action) {
 248                     if (action == null)
 249                         throw new NullPointerException();
 250                     if (it.hasNext()) {
 251                         action.accept(it.next());
 252                         return true;
 253                     }
 254                     else {
 255                         return false;
 256                     }
 257                 }
 258             }
 259             db.add("new Spliterators.AbstractSpliterator()",
 260                    () -> new SpliteratorFromIterator(exp.iterator(), exp.size()));
 261 
 262             // Collections
 263 
 264             // default method implementations
 265 
 266             class AbstractCollectionImpl extends AbstractCollection<Integer> {
 267                 Collection<Integer> c;
 268 
 269                 AbstractCollectionImpl(Collection<Integer> c) {
 270                     this.c = c;
 271                 }
 272 
 273                 @Override
 274                 public Iterator<Integer> iterator() {
 275                     return c.iterator();
 276                 }
 277 
 278                 @Override
 279                 public int size() {
 280                     return c.size();
 281                 }
 282             }
 283             db.addCollection(
 284                     c -> new AbstractCollectionImpl(c));
 285 
 286             class AbstractListImpl extends AbstractList<Integer> {
 287                 List<Integer> l;
 288 
 289                 AbstractListImpl(Collection<Integer> c) {
 290                     this.l = new ArrayList<>(c);
 291                 }
 292 
 293                 @Override
 294                 public Integer get(int index) {
 295                     return l.get(index);
 296                 }
 297 
 298                 @Override
 299                 public int size() {
 300                     return l.size();
 301                 }
 302             }
 303             db.addCollection(
 304                     c -> new AbstractListImpl(c));
 305 
 306             class AbstractSetImpl extends AbstractSet<Integer> {
 307                 Set<Integer> s;
 308 
 309                 AbstractSetImpl(Collection<Integer> c) {
 310                     this.s = new HashSet<>(c);
 311                 }
 312 
 313                 @Override
 314                 public Iterator<Integer> iterator() {
 315                     return s.iterator();
 316                 }
 317 
 318                 @Override
 319                 public int size() {
 320                     return s.size();
 321                 }
 322             }
 323             db.addCollection(
 324                     c -> new AbstractSetImpl(c));
 325 
 326             class AbstractSortedSetImpl extends AbstractSet<Integer> implements SortedSet<Integer> {
 327                 SortedSet<Integer> s;
 328 
 329                 AbstractSortedSetImpl(Collection<Integer> c) {
 330                     this.s = new TreeSet<>(c);
 331                 }
 332 
 333                 @Override
 334                 public Iterator<Integer> iterator() {
 335                     return s.iterator();
 336                 }
 337 
 338                 @Override
 339                 public int size() {
 340                     return s.size();
 341                 }
 342 
 343                 @Override
 344                 public Comparator<? super Integer> comparator() {
 345                     return s.comparator();
 346                 }
 347 
 348                 @Override
 349                 public SortedSet<Integer> subSet(Integer fromElement, Integer toElement) {
 350                     return s.subSet(fromElement, toElement);
 351                 }
 352 
 353                 @Override
 354                 public SortedSet<Integer> headSet(Integer toElement) {
 355                     return s.headSet(toElement);
 356                 }
 357 
 358                 @Override
 359                 public SortedSet<Integer> tailSet(Integer fromElement) {
 360                     return s.tailSet(fromElement);
 361                 }
 362 
 363                 @Override
 364                 public Integer first() {
 365                     return s.first();
 366                 }
 367 
 368                 @Override
 369                 public Integer last() {
 370                     return s.last();
 371                 }
 372 
 373                 @Override
 374                 public Spliterator<Integer> spliterator() {
 375                     return SortedSet.super.spliterator();
 376                 }
 377             }
 378             db.addCollection(
 379                     c -> new AbstractSortedSetImpl(c));
 380 
 381             class IterableWrapper implements Iterable<Integer> {
 382                 final Iterable<Integer> it;
 383 
 384                 IterableWrapper(Iterable<Integer> it) {
 385                     this.it = it;
 386                 }
 387 
 388                 @Override
 389                 public Iterator<Integer> iterator() {
 390                     return it.iterator();
 391                 }
 392             }
 393             db.add("new Iterable.spliterator()",
 394                    () -> new IterableWrapper(exp).spliterator());
 395 
 396             //
 397 
 398             db.add("Arrays.asList().spliterator()",
 399                    () -> Spliterators.spliterator(Arrays.asList(exp.toArray(new Integer[0])), 0));
 400 
 401             db.addList(ArrayList::new);
 402 
 403             db.addList(LinkedList::new);
 404 
 405             db.addList(Vector::new);
 406 
 407             class AbstractRandomAccessListImpl extends AbstractList<Integer> implements RandomAccess {
 408                 Integer[] ia;
 409 
 410                 AbstractRandomAccessListImpl(Collection<Integer> c) {
 411                     this.ia = c.toArray(new Integer[c.size()]);
 412                 }
 413 
 414                 @Override
 415                 public Integer get(int index) {
 416                     return ia[index];
 417                 }
 418 
 419                 @Override
 420                 public int size() {
 421                     return ia.length;
 422                 }
 423             }
 424             db.addList(AbstractRandomAccessListImpl::new);
 425 
 426             class RandomAccessListImpl implements List<Integer>, RandomAccess {
 427                 Integer[] ia;
 428                 List<Integer> l;
 429 
 430                 RandomAccessListImpl(Collection<Integer> c) {
 431                     this.ia = c.toArray(new Integer[c.size()]);
 432                     this.l = Arrays.asList(ia);
 433                 }
 434 
 435                 @Override
 436                 public Integer get(int index) {
 437                     return ia[index];
 438                 }
 439 
 440                 @Override
 441                 public Integer set(int index, Integer element) {
 442                     throw new UnsupportedOperationException();
 443                 }
 444 
 445                 @Override
 446                 public void add(int index, Integer element) {
 447                     throw new UnsupportedOperationException();
 448                 }
 449 
 450                 @Override
 451                 public Integer remove(int index) {
 452                     throw new UnsupportedOperationException();
 453                 }
 454 
 455                 @Override
 456                 public int indexOf(Object o) {
 457                     return l.indexOf(o);
 458                 }
 459 
 460                 @Override
 461                 public int lastIndexOf(Object o) {
 462                     return Arrays.asList(ia).lastIndexOf(o);
 463                 }
 464 
 465                 @Override
 466                 public ListIterator<Integer> listIterator() {
 467                     return l.listIterator();
 468                 }
 469 
 470                 @Override
 471                 public ListIterator<Integer> listIterator(int index) {
 472                     return l.listIterator(index);
 473                 }
 474 
 475                 @Override
 476                 public List<Integer> subList(int fromIndex, int toIndex) {
 477                     return l.subList(fromIndex, toIndex);
 478                 }
 479 
 480                 @Override
 481                 public int size() {
 482                     return ia.length;
 483                 }
 484 
 485                 @Override
 486                 public boolean isEmpty() {
 487                     return size() != 0;
 488                 }
 489 
 490                 @Override
 491                 public boolean contains(Object o) {
 492                     return l.contains(o);
 493                 }
 494 
 495                 @Override
 496                 public Iterator<Integer> iterator() {
 497                     return l.iterator();
 498                 }
 499 
 500                 @Override
 501                 public Object[] toArray() {
 502                     return l.toArray();
 503                 }
 504 
 505                 @Override
 506                 public <T> T[] toArray(T[] a) {
 507                     return l.toArray(a);
 508                 }
 509 
 510                 @Override
 511                 public boolean add(Integer integer) {
 512                     throw new UnsupportedOperationException();
 513                 }
 514 
 515                 @Override
 516                 public boolean remove(Object o) {
 517                     throw new UnsupportedOperationException();
 518                 }
 519 
 520                 @Override
 521                 public boolean containsAll(Collection<?> c) {
 522                     return l.containsAll(c);
 523                 }
 524 
 525                 @Override
 526                 public boolean addAll(Collection<? extends Integer> c) {
 527                     throw new UnsupportedOperationException();
 528                 }
 529 
 530                 @Override
 531                 public boolean addAll(int index, Collection<? extends Integer> c) {
 532                     throw new UnsupportedOperationException();
 533                 }
 534 
 535                 @Override
 536                 public boolean removeAll(Collection<?> c) {
 537                     throw new UnsupportedOperationException();
 538                 }
 539 
 540                 @Override
 541                 public boolean retainAll(Collection<?> c) {
 542                     throw new UnsupportedOperationException();
 543                 }
 544 
 545                 @Override
 546                 public void clear() {
 547                     throw new UnsupportedOperationException();
 548                 }
 549             }
 550             db.addList(RandomAccessListImpl::new);
 551 
 552             db.addCollection(HashSet::new);
 553 
 554             db.addCollection(LinkedHashSet::new);
 555 
 556             db.addCollection(TreeSet::new);
 557 
 558 
 559             db.addCollection(c -> { Stack<Integer> s = new Stack<>(); s.addAll(c); return s;});
 560 
 561             db.addCollection(PriorityQueue::new);
 562 
 563             db.addCollection(ArrayDeque::new);
 564 
 565 
 566             db.addCollection(ConcurrentSkipListSet::new);
 567 
 568             if (size > 0) {
 569                 db.addCollection(c -> {
 570                     ArrayBlockingQueue<Integer> abq = new ArrayBlockingQueue<>(size);
 571                     abq.addAll(c);
 572                     return abq;
 573                 });
 574             }
 575 
 576             db.addCollection(PriorityBlockingQueue::new);
 577 
 578             db.addCollection(LinkedBlockingQueue::new);
 579 
 580             db.addCollection(LinkedTransferQueue::new);
 581 
 582             db.addCollection(ConcurrentLinkedQueue::new);
 583 
 584             db.addCollection(LinkedBlockingDeque::new);
 585 
 586             db.addCollection(CopyOnWriteArrayList::new);
 587 
 588             db.addCollection(CopyOnWriteArraySet::new);
 589 
 590             if (size == 0) {
 591                 db.addCollection(c -> Collections.<Integer>emptySet());
 592                 db.addList(c -> Collections.<Integer>emptyList());
 593             }
 594             else if (size == 1) {
 595                 db.addCollection(c -> Collections.singleton(exp.get(0)));
 596                 db.addCollection(c -> Collections.singletonList(exp.get(0)));
 597             }
 598 
 599             {
 600                 Integer[] ai = new Integer[size];
 601                 Arrays.fill(ai, 1);
 602                 db.add(String.format("Collections.nCopies(%d, 1)", exp.size()),
 603                        Arrays.asList(ai),
 604                        () -> Collections.nCopies(exp.size(), 1).spliterator());
 605             }
 606 
 607             // Collections.synchronized/unmodifiable/checked wrappers
 608             db.addCollection(Collections::unmodifiableCollection);
 609             db.addCollection(c -> Collections.unmodifiableSet(new HashSet<>(c)));
 610             db.addCollection(c -> Collections.unmodifiableSortedSet(new TreeSet<>(c)));
 611             db.addList(c -> Collections.unmodifiableList(new ArrayList<>(c)));
 612             db.addMap(Collections::unmodifiableMap);
 613             db.addMap(m -> Collections.unmodifiableSortedMap(new TreeMap<>(m)));
 614 
 615             db.addCollection(Collections::synchronizedCollection);
 616             db.addCollection(c -> Collections.synchronizedSet(new HashSet<>(c)));
 617             db.addCollection(c -> Collections.synchronizedSortedSet(new TreeSet<>(c)));
 618             db.addList(c -> Collections.synchronizedList(new ArrayList<>(c)));
 619             db.addMap(Collections::synchronizedMap);
 620             db.addMap(m -> Collections.synchronizedSortedMap(new TreeMap<>(m)));
 621 
 622             db.addCollection(c -> Collections.checkedCollection(c, Integer.class));
 623             db.addCollection(c -> Collections.checkedQueue(new ArrayDeque<>(c), Integer.class));
 624             db.addCollection(c -> Collections.checkedSet(new HashSet<>(c), Integer.class));
 625             db.addCollection(c -> Collections.checkedSortedSet(new TreeSet<>(c), Integer.class));
 626             db.addList(c -> Collections.checkedList(new ArrayList<>(c), Integer.class));
 627             db.addMap(c -> Collections.checkedMap(c, Integer.class, Integer.class));
 628             db.addMap(m -> Collections.checkedSortedMap(new TreeMap<>(m), Integer.class, Integer.class));
 629 
 630             // Maps
 631 
 632             db.addMap(HashMap::new);
 633 
 634             db.addMap(m -> {
 635                 // Create a Map ensuring that for large sizes
 636                 // buckets will contain 2 or more entries
 637                 HashMap<Integer, Integer> cm = new HashMap<>(1, m.size() + 1);
 638                 // Don't use putAll which inflates the table by
 639                 // m.size() * loadFactor, thus creating a very sparse
 640                 // map for 1000 entries defeating the purpose of this test,
 641                 // in addition it will cause the split until null test to fail
 642                 // because the number of valid splits is larger than the
 643                 // threshold
 644                 for (Map.Entry<Integer, Integer> e : m.entrySet())
 645                     cm.put(e.getKey(), e.getValue());
 646                 return cm;
 647             }, "new java.util.HashMap(1, size + 1)");
 648 
 649             db.addMap(LinkedHashMap::new);
 650 
 651             db.addMap(IdentityHashMap::new);
 652 
 653             if (!PreviewFeatures.isEnabled()) {
 654                 // With --enable-preview, WeakHashmap is not tested with Integer, a value class
 655                 db.addMap(WeakHashMap::new);
 656 
 657                 db.addMap(m -> {
 658                     // Create a Map ensuring that for large sizes
 659                     // buckets will consist of 2 or more entries
 660                     WeakHashMap<Integer, Integer> cm = new WeakHashMap<>(1, m.size() + 1);
 661                     for (Map.Entry<Integer, Integer> e : m.entrySet())
 662                         cm.put(e.getKey(), e.getValue());
 663                     return cm;
 664                 }, "new java.util.WeakHashMap(1, size + 1)");
 665             }
 666 
 667             db.addMap(TreeMap::new);
 668             db.addMap(m -> new TreeMap<>(m).tailMap(Integer.MIN_VALUE));
 669             db.addMap(m -> new TreeMap<>(m).headMap(Integer.MAX_VALUE));
 670             db.addMap(m -> new TreeMap<>(m).subMap(Integer.MIN_VALUE, Integer.MAX_VALUE));
 671             db.addDescendingMap(m -> new TreeMap<>(m).descendingMap());
 672             db.addDescendingMap(m -> new TreeMap<>(m).descendingMap().tailMap(Integer.MAX_VALUE));
 673             db.addDescendingMap(m -> new TreeMap<>(m).descendingMap().headMap(Integer.MIN_VALUE));
 674             db.addDescendingMap(m -> new TreeMap<>(m).descendingMap().subMap(Integer.MAX_VALUE, Integer.MIN_VALUE));
 675 
 676             db.addMap(ConcurrentHashMap::new);
 677 
 678             db.addMap(ConcurrentSkipListMap::new);
 679 
 680             if (size == 0) {
 681                 db.addMap(m -> Collections.<Integer, Integer>emptyMap());
 682             }
 683             else if (size == 1) {
 684                 db.addMap(m -> Collections.singletonMap(exp.get(0), exp.get(0)));
 685             }
 686         }
 687 
 688         return spliteratorDataProvider = data.toArray(new Object[0][]);
 689     }
 690 
 691     private static List<Integer> listIntRange(int upTo) {
 692         List<Integer> exp = new ArrayList<>();
 693         for (int i = 0; i < upTo; i++)
 694             exp.add(i);
 695         return Collections.unmodifiableList(exp);
 696     }
 697 
 698     @Test(dataProvider = "Spliterator<Integer>")
 699     public void testNullPointerException(String description, Collection<Integer> exp, Supplier<Spliterator<Integer>> s) {
 700         assertThrowsNPE(() -> s.get().forEachRemaining(null));
 701         assertThrowsNPE(() -> s.get().tryAdvance(null));
 702     }
 703 
 704     @Test(dataProvider = "Spliterator<Integer>")
 705     public void testForEach(String description, Collection<Integer> exp, Supplier<Spliterator<Integer>> s) {
 706         testForEach(exp, s, UnaryOperator.identity());
 707     }
 708 
 709     @Test(dataProvider = "Spliterator<Integer>")
 710     public void testTryAdvance(String description, Collection<Integer> exp, Supplier<Spliterator<Integer>> s) {
 711         testTryAdvance(exp, s, UnaryOperator.identity());
 712     }
 713 
 714     @Test(dataProvider = "Spliterator<Integer>")
 715     public void testMixedTryAdvanceForEach(String description, Collection<Integer> exp, Supplier<Spliterator<Integer>> s) {
 716         testMixedTryAdvanceForEach(exp, s, UnaryOperator.identity());
 717     }
 718 
 719     @Test(dataProvider = "Spliterator<Integer>")
 720     public void testMixedTraverseAndSplit(String description, Collection<Integer> exp, Supplier<Spliterator<Integer>> s) {
 721         testMixedTraverseAndSplit(exp, s, UnaryOperator.identity());
 722     }
 723 
 724     @Test(dataProvider = "Spliterator<Integer>")
 725     public void testSplitAfterFullTraversal(String description, Collection<Integer> exp, Supplier<Spliterator<Integer>> s) {
 726         testSplitAfterFullTraversal(s, UnaryOperator.identity());
 727     }
 728 
 729     @Test(dataProvider = "Spliterator<Integer>")
 730     public void testSplitOnce(String description, Collection<Integer> exp, Supplier<Spliterator<Integer>> s) {
 731         testSplitOnce(exp, s, UnaryOperator.identity());
 732     }
 733 
 734     @Test(dataProvider = "Spliterator<Integer>")
 735     public void testSplitSixDeep(String description, Collection<Integer> exp, Supplier<Spliterator<Integer>> s) {
 736         testSplitSixDeep(exp, s, UnaryOperator.identity());
 737     }
 738 
 739     @Test(dataProvider = "Spliterator<Integer>")
 740     public void testSplitUntilNull(String description, Collection<Integer> exp, Supplier<Spliterator<Integer>> s) {
 741         testSplitUntilNull(exp, s, UnaryOperator.identity());
 742     }
 743 
 744     //
 745     private static class SpliteratorOfIntCharDataBuilder {
 746         List<Object[]> data;
 747 
 748         String s;
 749 
 750         List<Integer> expChars;
 751 
 752         List<Integer> expCodePoints;
 753 
 754         SpliteratorOfIntCharDataBuilder(List<Object[]> data, String s) {
 755             this.data = data;
 756             this.s = s;
 757             this.expChars = transform(s, false);
 758             this.expCodePoints = transform(s, true);
 759         }
 760 
 761         static List<Integer> transform(String s, boolean toCodePoints) {
 762             List<Integer> l = new ArrayList<>();
 763 
 764             if (!toCodePoints) {
 765                 for (int i = 0; i < s.length(); i++) {
 766                     l.add((int) s.charAt(i));
 767                 }
 768             }
 769             else {
 770                 for (int i = 0; i < s.length();) {
 771                     char c1 = s.charAt(i++);
 772                     int cp = c1;
 773                     if (Character.isHighSurrogate(c1) && i < s.length()) {
 774                         char c2 = s.charAt(i);
 775                         if (Character.isLowSurrogate(c2)) {
 776                             i++;
 777                             cp = Character.toCodePoint(c1, c2);
 778                         }
 779                     }
 780                     l.add(cp);
 781                 }
 782             }
 783             return l;
 784         }
 785 
 786         void add(String description, Function<String, CharSequence> f) {
 787             description = description.replace("%s", s);
 788             {
 789                 Supplier<Spliterator.OfInt> supplier = () -> f.apply(s).chars().spliterator();
 790                 data.add(new Object[]{description + ".chars().spliterator()", expChars, supplier});
 791             }
 792             {
 793                 Supplier<Spliterator.OfInt> supplier = () -> f.apply(s).codePoints().spliterator();
 794                 data.add(new Object[]{description + ".codePoints().spliterator()", expCodePoints, supplier});
 795             }
 796         }
 797     }
 798 
 799     static Object[][] spliteratorOfIntDataProvider;
 800 
 801     @DataProvider(name = "Spliterator.OfInt")
 802     public static Object[][] spliteratorOfIntDataProvider() {
 803         if (spliteratorOfIntDataProvider != null) {
 804             return spliteratorOfIntDataProvider;
 805         }
 806 
 807         List<Object[]> data = new ArrayList<>();
 808         for (int size : SIZES) {
 809             int exp[] = arrayIntRange(size);
 810             SpliteratorOfIntDataBuilder db = new SpliteratorOfIntDataBuilder(data, listIntRange(size));
 811 
 812             db.add("Spliterators.spliterator(int[], ...)",
 813                    () -> Spliterators.spliterator(exp, 0));
 814 
 815             db.add("Arrays.spliterator(int[], ...)",
 816                    () -> Arrays.spliterator(exp));
 817 
 818             db.add("Spliterators.spliterator(PrimitiveIterator.OfInt, ...)",
 819                    () -> Spliterators.spliterator(Spliterators.iterator(Arrays.spliterator(exp)), exp.length, 0));
 820 
 821             db.add("Spliterators.spliteratorUnknownSize(PrimitiveIterator.OfInt, ...)",
 822                    () -> Spliterators.spliteratorUnknownSize(Spliterators.iterator(Arrays.spliterator(exp)), 0));
 823 
 824             class IntSpliteratorFromArray extends Spliterators.AbstractIntSpliterator {
 825                 int[] a;
 826                 int index = 0;
 827 
 828                 IntSpliteratorFromArray(int[] a) {
 829                     super(a.length, Spliterator.SIZED);
 830                     this.a = a;
 831                 }
 832 
 833                 @Override
 834                 public boolean tryAdvance(IntConsumer action) {
 835                     if (action == null)
 836                         throw new NullPointerException();
 837                     if (index < a.length) {
 838                         action.accept(a[index++]);
 839                         return true;
 840                     }
 841                     else {
 842                         return false;
 843                     }
 844                 }
 845             }
 846             db.add("new Spliterators.AbstractIntAdvancingSpliterator()",
 847                    () -> new IntSpliteratorFromArray(exp));
 848         }
 849 
 850         // Class for testing default methods
 851         class CharSequenceImpl implements CharSequence {
 852             final String s;
 853 
 854             public CharSequenceImpl(String s) {
 855                 this.s = s;
 856             }
 857 
 858             @Override
 859             public int length() {
 860                 return s.length();
 861             }
 862 
 863             @Override
 864             public char charAt(int index) {
 865                 return s.charAt(index);
 866             }
 867 
 868             @Override
 869             public CharSequence subSequence(int start, int end) {
 870                 return s.subSequence(start, end);
 871             }
 872 
 873             @Override
 874             public String toString() {
 875                 return s;
 876             }
 877         }
 878 
 879         for (String string : STRINGS) {
 880             SpliteratorOfIntCharDataBuilder cdb = new SpliteratorOfIntCharDataBuilder(data, string);
 881             cdb.add("\"%s\"", s -> s);
 882             cdb.add("new CharSequenceImpl(\"%s\")", CharSequenceImpl::new);
 883             cdb.add("new StringBuilder(\"%s\")", StringBuilder::new);
 884             cdb.add("new StringBuffer(\"%s\")", StringBuffer::new);
 885             cdb.add("CharBuffer.wrap(\"%s\".toCharArray())", s -> CharBuffer.wrap(s.toCharArray()));
 886         }
 887 
 888         return spliteratorOfIntDataProvider = data.toArray(new Object[0][]);
 889     }
 890 
 891     private static int[] arrayIntRange(int upTo) {
 892         int[] exp = new int[upTo];
 893         for (int i = 0; i < upTo; i++)
 894             exp[i] = i;
 895         return exp;
 896     }
 897 
 898     @Test(dataProvider = "Spliterator.OfInt")
 899     public void testIntNullPointerException(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
 900         assertThrowsNPE(() -> s.get().forEachRemaining((IntConsumer) null));
 901         assertThrowsNPE(() -> s.get().tryAdvance((IntConsumer) null));
 902     }
 903 
 904     @Test(dataProvider = "Spliterator.OfInt")
 905     public void testIntForEach(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
 906         testForEach(exp, s, intBoxingConsumer());
 907     }
 908 
 909     @Test(dataProvider = "Spliterator.OfInt")
 910     public void testIntTryAdvance(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
 911         testTryAdvance(exp, s, intBoxingConsumer());
 912     }
 913 
 914     @Test(dataProvider = "Spliterator.OfInt")
 915     public void testIntMixedTryAdvanceForEach(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
 916         testMixedTryAdvanceForEach(exp, s, intBoxingConsumer());
 917     }
 918 
 919     @Test(dataProvider = "Spliterator.OfInt")
 920     public void testIntMixedTraverseAndSplit(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
 921         testMixedTraverseAndSplit(exp, s, intBoxingConsumer());
 922     }
 923 
 924     @Test(dataProvider = "Spliterator.OfInt")
 925     public void testIntSplitAfterFullTraversal(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
 926         testSplitAfterFullTraversal(s, intBoxingConsumer());
 927     }
 928 
 929     @Test(dataProvider = "Spliterator.OfInt")
 930     public void testIntSplitOnce(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
 931         testSplitOnce(exp, s, intBoxingConsumer());
 932     }
 933 
 934     @Test(dataProvider = "Spliterator.OfInt")
 935     public void testIntSplitSixDeep(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
 936         testSplitSixDeep(exp, s, intBoxingConsumer());
 937     }
 938 
 939     @Test(dataProvider = "Spliterator.OfInt")
 940     public void testIntSplitUntilNull(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
 941         testSplitUntilNull(exp, s, intBoxingConsumer());
 942     }
 943 
 944     //
 945 
 946     private static class SpliteratorOfLongDataBuilder {
 947         List<Object[]> data;
 948 
 949         List<Long> exp;
 950 
 951         SpliteratorOfLongDataBuilder(List<Object[]> data, List<Long> exp) {
 952             this.data = data;
 953             this.exp = exp;
 954         }
 955 
 956         void add(String description, List<Long> expected, Supplier<Spliterator.OfLong> s) {
 957             description = joiner(description).toString();
 958             data.add(new Object[]{description, expected, s});
 959         }
 960 
 961         void add(String description, Supplier<Spliterator.OfLong> s) {
 962             add(description, exp, s);
 963         }
 964 
 965         StringBuilder joiner(String description) {
 966             return new StringBuilder(description).
 967                     append(" {").
 968                     append("size=").append(exp.size()).
 969                     append("}");
 970         }
 971     }
 972 
 973     static Object[][] spliteratorOfLongDataProvider;
 974 
 975     @DataProvider(name = "Spliterator.OfLong")
 976     public static Object[][] spliteratorOfLongDataProvider() {
 977         if (spliteratorOfLongDataProvider != null) {
 978             return spliteratorOfLongDataProvider;
 979         }
 980 
 981         List<Object[]> data = new ArrayList<>();
 982         for (int size : SIZES) {
 983             long exp[] = arrayLongRange(size);
 984             SpliteratorOfLongDataBuilder db = new SpliteratorOfLongDataBuilder(data, listLongRange(size));
 985 
 986             db.add("Spliterators.spliterator(long[], ...)",
 987                    () -> Spliterators.spliterator(exp, 0));
 988 
 989             db.add("Arrays.spliterator(long[], ...)",
 990                    () -> Arrays.spliterator(exp));
 991 
 992             db.add("Spliterators.spliterator(PrimitiveIterator.OfLong, ...)",
 993                    () -> Spliterators.spliterator(Spliterators.iterator(Arrays.spliterator(exp)), exp.length, 0));
 994 
 995             db.add("Spliterators.spliteratorUnknownSize(PrimitiveIterator.OfLong, ...)",
 996                    () -> Spliterators.spliteratorUnknownSize(Spliterators.iterator(Arrays.spliterator(exp)), 0));
 997 
 998             class LongSpliteratorFromArray extends Spliterators.AbstractLongSpliterator {
 999                 long[] a;
1000                 int index = 0;
1001 
1002                 LongSpliteratorFromArray(long[] a) {
1003                     super(a.length, Spliterator.SIZED);
1004                     this.a = a;
1005                 }
1006 
1007                 @Override
1008                 public boolean tryAdvance(LongConsumer action) {
1009                     if (action == null)
1010                         throw new NullPointerException();
1011                     if (index < a.length) {
1012                         action.accept(a[index++]);
1013                         return true;
1014                     }
1015                     else {
1016                         return false;
1017                     }
1018                 }
1019             }
1020             db.add("new Spliterators.AbstractLongAdvancingSpliterator()",
1021                    () -> new LongSpliteratorFromArray(exp));
1022         }
1023 
1024         return spliteratorOfLongDataProvider = data.toArray(new Object[0][]);
1025     }
1026 
1027     private static List<Long> listLongRange(int upTo) {
1028         List<Long> exp = new ArrayList<>();
1029         for (long i = 0; i < upTo; i++)
1030             exp.add(i);
1031         return Collections.unmodifiableList(exp);
1032     }
1033 
1034     private static long[] arrayLongRange(int upTo) {
1035         long[] exp = new long[upTo];
1036         for (int i = 0; i < upTo; i++)
1037             exp[i] = i;
1038         return exp;
1039     }
1040 
1041     @Test(dataProvider = "Spliterator.OfLong")
1042     public void testLongNullPointerException(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
1043         assertThrowsNPE(() -> s.get().forEachRemaining((LongConsumer) null));
1044         assertThrowsNPE(() -> s.get().tryAdvance((LongConsumer) null));
1045     }
1046 
1047     @Test(dataProvider = "Spliterator.OfLong")
1048     public void testLongForEach(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
1049         testForEach(exp, s, longBoxingConsumer());
1050     }
1051 
1052     @Test(dataProvider = "Spliterator.OfLong")
1053     public void testLongTryAdvance(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
1054         testTryAdvance(exp, s, longBoxingConsumer());
1055     }
1056 
1057     @Test(dataProvider = "Spliterator.OfLong")
1058     public void testLongMixedTryAdvanceForEach(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
1059         testMixedTryAdvanceForEach(exp, s, longBoxingConsumer());
1060     }
1061 
1062     @Test(dataProvider = "Spliterator.OfLong")
1063     public void testLongMixedTraverseAndSplit(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
1064         testMixedTraverseAndSplit(exp, s, longBoxingConsumer());
1065     }
1066 
1067     @Test(dataProvider = "Spliterator.OfLong")
1068     public void testLongSplitAfterFullTraversal(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
1069         testSplitAfterFullTraversal(s, longBoxingConsumer());
1070     }
1071 
1072     @Test(dataProvider = "Spliterator.OfLong")
1073     public void testLongSplitOnce(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
1074         testSplitOnce(exp, s, longBoxingConsumer());
1075     }
1076 
1077     @Test(dataProvider = "Spliterator.OfLong")
1078     public void testLongSplitSixDeep(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
1079         testSplitSixDeep(exp, s, longBoxingConsumer());
1080     }
1081 
1082     @Test(dataProvider = "Spliterator.OfLong")
1083     public void testLongSplitUntilNull(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
1084         testSplitUntilNull(exp, s, longBoxingConsumer());
1085     }
1086 
1087     //
1088 
1089     private static class SpliteratorOfDoubleDataBuilder {
1090         List<Object[]> data;
1091 
1092         List<Double> exp;
1093 
1094         SpliteratorOfDoubleDataBuilder(List<Object[]> data, List<Double> exp) {
1095             this.data = data;
1096             this.exp = exp;
1097         }
1098 
1099         void add(String description, List<Double> expected, Supplier<Spliterator.OfDouble> s) {
1100             description = joiner(description).toString();
1101             data.add(new Object[]{description, expected, s});
1102         }
1103 
1104         void add(String description, Supplier<Spliterator.OfDouble> s) {
1105             add(description, exp, s);
1106         }
1107 
1108         StringBuilder joiner(String description) {
1109             return new StringBuilder(description).
1110                     append(" {").
1111                     append("size=").append(exp.size()).
1112                     append("}");
1113         }
1114     }
1115 
1116     static Object[][] spliteratorOfDoubleDataProvider;
1117 
1118     @DataProvider(name = "Spliterator.OfDouble")
1119     public static Object[][] spliteratorOfDoubleDataProvider() {
1120         if (spliteratorOfDoubleDataProvider != null) {
1121             return spliteratorOfDoubleDataProvider;
1122         }
1123 
1124         List<Object[]> data = new ArrayList<>();
1125         for (int size : SIZES) {
1126             double exp[] = arrayDoubleRange(size);
1127             SpliteratorOfDoubleDataBuilder db = new SpliteratorOfDoubleDataBuilder(data, listDoubleRange(size));
1128 
1129             db.add("Spliterators.spliterator(double[], ...)",
1130                    () -> Spliterators.spliterator(exp, 0));
1131 
1132             db.add("Arrays.spliterator(double[], ...)",
1133                    () -> Arrays.spliterator(exp));
1134 
1135             db.add("Spliterators.spliterator(PrimitiveIterator.OfDouble, ...)",
1136                    () -> Spliterators.spliterator(Spliterators.iterator(Arrays.spliterator(exp)), exp.length, 0));
1137 
1138             db.add("Spliterators.spliteratorUnknownSize(PrimitiveIterator.OfDouble, ...)",
1139                    () -> Spliterators.spliteratorUnknownSize(Spliterators.iterator(Arrays.spliterator(exp)), 0));
1140 
1141             class DoubleSpliteratorFromArray extends Spliterators.AbstractDoubleSpliterator {
1142                 double[] a;
1143                 int index = 0;
1144 
1145                 DoubleSpliteratorFromArray(double[] a) {
1146                     super(a.length, Spliterator.SIZED);
1147                     this.a = a;
1148                 }
1149 
1150                 @Override
1151                 public boolean tryAdvance(DoubleConsumer action) {
1152                     if (action == null)
1153                         throw new NullPointerException();
1154                     if (index < a.length) {
1155                         action.accept(a[index++]);
1156                         return true;
1157                     }
1158                     else {
1159                         return false;
1160                     }
1161                 }
1162             }
1163             db.add("new Spliterators.AbstractDoubleAdvancingSpliterator()",
1164                    () -> new DoubleSpliteratorFromArray(exp));
1165         }
1166 
1167         return spliteratorOfDoubleDataProvider = data.toArray(new Object[0][]);
1168     }
1169 
1170     private static List<Double> listDoubleRange(int upTo) {
1171         List<Double> exp = new ArrayList<>();
1172         for (double i = 0; i < upTo; i++)
1173             exp.add(i);
1174         return Collections.unmodifiableList(exp);
1175     }
1176 
1177     private static double[] arrayDoubleRange(int upTo) {
1178         double[] exp = new double[upTo];
1179         for (int i = 0; i < upTo; i++)
1180             exp[i] = i;
1181         return exp;
1182     }
1183 
1184     @Test(dataProvider = "Spliterator.OfDouble")
1185     public void testDoubleNullPointerException(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
1186         assertThrowsNPE(() -> s.get().forEachRemaining((DoubleConsumer) null));
1187         assertThrowsNPE(() -> s.get().tryAdvance((DoubleConsumer) null));
1188     }
1189 
1190     @Test(dataProvider = "Spliterator.OfDouble")
1191     public void testDoubleForEach(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
1192         testForEach(exp, s, doubleBoxingConsumer());
1193     }
1194 
1195     @Test(dataProvider = "Spliterator.OfDouble")
1196     public void testDoubleTryAdvance(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
1197         testTryAdvance(exp, s, doubleBoxingConsumer());
1198     }
1199 
1200     @Test(dataProvider = "Spliterator.OfDouble")
1201     public void testDoubleMixedTryAdvanceForEach(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
1202         testMixedTryAdvanceForEach(exp, s, doubleBoxingConsumer());
1203     }
1204 
1205     @Test(dataProvider = "Spliterator.OfDouble")
1206     public void testDoubleMixedTraverseAndSplit(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
1207         testMixedTraverseAndSplit(exp, s, doubleBoxingConsumer());
1208     }
1209 
1210     @Test(dataProvider = "Spliterator.OfDouble")
1211     public void testDoubleSplitAfterFullTraversal(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
1212         testSplitAfterFullTraversal(s, doubleBoxingConsumer());
1213     }
1214 
1215     @Test(dataProvider = "Spliterator.OfDouble")
1216     public void testDoubleSplitOnce(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
1217         testSplitOnce(exp, s, doubleBoxingConsumer());
1218     }
1219 
1220     @Test(dataProvider = "Spliterator.OfDouble")
1221     public void testDoubleSplitSixDeep(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
1222         testSplitSixDeep(exp, s, doubleBoxingConsumer());
1223     }
1224 
1225     @Test(dataProvider = "Spliterator.OfDouble")
1226     public void testDoubleSplitUntilNull(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
1227         testSplitUntilNull(exp, s, doubleBoxingConsumer());
1228     }
1229 
1230 }