< prev index next >

src/java.base/share/classes/java/util/stream/StreamSpliterators.java

Print this page




 139          */
 140         final void init() {
 141             if (spliterator == null) {
 142                 spliterator = spliteratorSupplier.get();
 143                 spliteratorSupplier = null;
 144             }
 145         }
 146 
 147         /**
 148          * Get an element from the source, pushing it into the sink chain,
 149          * setting up the buffer if needed
 150          * @return whether there are elements to consume from the buffer
 151          */
 152         final boolean doAdvance() {
 153             if (buffer == null) {
 154                 if (finished)
 155                     return false;
 156 
 157                 init();
 158                 initPartialTraversalState();

 159                 nextToConsume = 0;
 160                 bufferSink.begin(spliterator.getExactSizeIfKnown());
 161                 return fillBuffer();
 162             }
 163             else {
 164                 ++nextToConsume;
 165                 boolean hasNext = nextToConsume < buffer.count();
 166                 if (!hasNext) {
 167                     nextToConsume = 0;
 168                     buffer.clear();
 169                     hasNext = fillBuffer();
 170                 }
 171                 return hasNext;
 172             }
 173         }
 174 
 175         /**
 176          * Invokes the shape-specific constructor with the provided arguments
 177          * and returns the result.
 178          */
 179         abstract AbstractWrappingSpliterator<P_IN, P_OUT, ?> wrap(Spliterator<P_IN> s);
 180 
 181         /**
 182          * Initializes buffer, sink chain, and pusher for a shape-specific
 183          * implementation.
 184          */
 185         abstract void initPartialTraversalState();
 186 




 187         @Override
 188         public Spliterator<P_OUT> trySplit() {
 189             if (isParallel && !finished) {
 190                 init();
 191 
 192                 Spliterator<P_IN> split = spliterator.trySplit();
 193                 return (split == null) ? null : wrap(split);










 194             }
 195             else
 196                 return null;
 197         }
 198 
 199         /**
 200          * If the buffer is empty, push elements into the sink chain until
 201          * the source is empty or cancellation is requested.
 202          * @return whether there are elements to consume from the buffer
 203          */
 204         private boolean fillBuffer() {
 205             while (buffer.count() == 0) {
 206                 if (bufferSink.cancellationRequested() || !pusher.getAsBoolean()) {
 207                     if (finished)
 208                         return false;
 209                     else {
 210                         bufferSink.end(); // might trigger more elements
 211                         finished = true;
 212                     }
 213                 }


 274                             boolean parallel) {
 275             super(ph, supplier, parallel);
 276         }
 277 
 278         WrappingSpliterator(PipelineHelper<P_OUT> ph,
 279                             Spliterator<P_IN> spliterator,
 280                             boolean parallel) {
 281             super(ph, spliterator, parallel);
 282         }
 283 
 284         @Override
 285         WrappingSpliterator<P_IN, P_OUT> wrap(Spliterator<P_IN> s) {
 286             return new WrappingSpliterator<>(ph, s, isParallel);
 287         }
 288 
 289         @Override
 290         void initPartialTraversalState() {
 291             SpinedBuffer<P_OUT> b = new SpinedBuffer<>();
 292             buffer = b;
 293             bufferSink = ph.wrapSink(b::accept);
 294             pusher = () -> spliterator.tryAdvance(bufferSink);
 295         }
 296 
 297         @Override
 298         public boolean tryAdvance(Consumer<? super P_OUT> consumer) {
 299             Objects.requireNonNull(consumer);
 300             boolean hasNext = doAdvance();
 301             if (hasNext)
 302                 consumer.accept(buffer.get(nextToConsume));
 303             return hasNext;
 304         }
 305 
 306         @Override
 307         public void forEachRemaining(Consumer<? super P_OUT> consumer) {
 308             if (buffer == null && !finished) {
 309                 Objects.requireNonNull(consumer);
 310                 init();
 311 
 312                 ph.wrapAndCopyInto((Sink<P_OUT>) consumer::accept, spliterator);
 313                 finished = true;
 314             }


 318         }
 319     }
 320 
 321     static final class IntWrappingSpliterator<P_IN>
 322             extends AbstractWrappingSpliterator<P_IN, Integer, SpinedBuffer.OfInt>
 323             implements Spliterator.OfInt {
 324 
 325         IntWrappingSpliterator(PipelineHelper<Integer> ph,
 326                                Supplier<Spliterator<P_IN>> supplier,
 327                                boolean parallel) {
 328             super(ph, supplier, parallel);
 329         }
 330 
 331         IntWrappingSpliterator(PipelineHelper<Integer> ph,
 332                                Spliterator<P_IN> spliterator,
 333                                boolean parallel) {
 334             super(ph, spliterator, parallel);
 335         }
 336 
 337         @Override
 338         AbstractWrappingSpliterator<P_IN, Integer, ?> wrap(Spliterator<P_IN> s) {
 339             return new IntWrappingSpliterator<>(ph, s, isParallel);
 340         }
 341 
 342         @Override
 343         void initPartialTraversalState() {
 344             SpinedBuffer.OfInt b = new SpinedBuffer.OfInt();
 345             buffer = b;
 346             bufferSink = ph.wrapSink((Sink.OfInt) b::accept);
 347             pusher = () -> spliterator.tryAdvance(bufferSink);
 348         }
 349 
 350         @Override
 351         public Spliterator.OfInt trySplit() {
 352             return (Spliterator.OfInt) super.trySplit();
 353         }
 354 
 355         @Override
 356         public boolean tryAdvance(IntConsumer consumer) {
 357             Objects.requireNonNull(consumer);
 358             boolean hasNext = doAdvance();
 359             if (hasNext)
 360                 consumer.accept(buffer.get(nextToConsume));
 361             return hasNext;
 362         }
 363 
 364         @Override
 365         public void forEachRemaining(IntConsumer consumer) {
 366             if (buffer == null && !finished) {
 367                 Objects.requireNonNull(consumer);


 376         }
 377     }
 378 
 379     static final class LongWrappingSpliterator<P_IN>
 380             extends AbstractWrappingSpliterator<P_IN, Long, SpinedBuffer.OfLong>
 381             implements Spliterator.OfLong {
 382 
 383         LongWrappingSpliterator(PipelineHelper<Long> ph,
 384                                 Supplier<Spliterator<P_IN>> supplier,
 385                                 boolean parallel) {
 386             super(ph, supplier, parallel);
 387         }
 388 
 389         LongWrappingSpliterator(PipelineHelper<Long> ph,
 390                                 Spliterator<P_IN> spliterator,
 391                                 boolean parallel) {
 392             super(ph, spliterator, parallel);
 393         }
 394 
 395         @Override
 396         AbstractWrappingSpliterator<P_IN, Long, ?> wrap(Spliterator<P_IN> s) {
 397             return new LongWrappingSpliterator<>(ph, s, isParallel);
 398         }
 399 
 400         @Override
 401         void initPartialTraversalState() {
 402             SpinedBuffer.OfLong b = new SpinedBuffer.OfLong();
 403             buffer = b;
 404             bufferSink = ph.wrapSink((Sink.OfLong) b::accept);
 405             pusher = () -> spliterator.tryAdvance(bufferSink);
 406         }
 407 
 408         @Override
 409         public Spliterator.OfLong trySplit() {
 410             return (Spliterator.OfLong) super.trySplit();
 411         }
 412 
 413         @Override
 414         public boolean tryAdvance(LongConsumer consumer) {
 415             Objects.requireNonNull(consumer);
 416             boolean hasNext = doAdvance();
 417             if (hasNext)
 418                 consumer.accept(buffer.get(nextToConsume));
 419             return hasNext;
 420         }
 421 
 422         @Override
 423         public void forEachRemaining(LongConsumer consumer) {
 424             if (buffer == null && !finished) {
 425                 Objects.requireNonNull(consumer);


 434         }
 435     }
 436 
 437     static final class DoubleWrappingSpliterator<P_IN>
 438             extends AbstractWrappingSpliterator<P_IN, Double, SpinedBuffer.OfDouble>
 439             implements Spliterator.OfDouble {
 440 
 441         DoubleWrappingSpliterator(PipelineHelper<Double> ph,
 442                                   Supplier<Spliterator<P_IN>> supplier,
 443                                   boolean parallel) {
 444             super(ph, supplier, parallel);
 445         }
 446 
 447         DoubleWrappingSpliterator(PipelineHelper<Double> ph,
 448                                   Spliterator<P_IN> spliterator,
 449                                   boolean parallel) {
 450             super(ph, spliterator, parallel);
 451         }
 452 
 453         @Override
 454         AbstractWrappingSpliterator<P_IN, Double, ?> wrap(Spliterator<P_IN> s) {
 455             return new DoubleWrappingSpliterator<>(ph, s, isParallel);
 456         }
 457 
 458         @Override
 459         void initPartialTraversalState() {
 460             SpinedBuffer.OfDouble b = new SpinedBuffer.OfDouble();
 461             buffer = b;
 462             bufferSink = ph.wrapSink((Sink.OfDouble) b::accept);
 463             pusher = () -> spliterator.tryAdvance(bufferSink);
 464         }
 465 
 466         @Override
 467         public Spliterator.OfDouble trySplit() {
 468             return (Spliterator.OfDouble) super.trySplit();
 469         }
 470 
 471         @Override
 472         public boolean tryAdvance(DoubleConsumer consumer) {
 473             Objects.requireNonNull(consumer);
 474             boolean hasNext = doAdvance();
 475             if (hasNext)
 476                 consumer.accept(buffer.get(nextToConsume));
 477             return hasNext;
 478         }
 479 
 480         @Override
 481         public void forEachRemaining(DoubleConsumer consumer) {
 482             if (buffer == null && !finished) {
 483                 Objects.requireNonNull(consumer);




 139          */
 140         final void init() {
 141             if (spliterator == null) {
 142                 spliterator = spliteratorSupplier.get();
 143                 spliteratorSupplier = null;
 144             }
 145         }
 146 
 147         /**
 148          * Get an element from the source, pushing it into the sink chain,
 149          * setting up the buffer if needed
 150          * @return whether there are elements to consume from the buffer
 151          */
 152         final boolean doAdvance() {
 153             if (buffer == null) {
 154                 if (finished)
 155                     return false;
 156 
 157                 init();
 158                 initPartialTraversalState();
 159                 initPusher();
 160                 nextToConsume = 0;
 161                 bufferSink.begin(spliterator.getExactSizeIfKnown());
 162                 return fillBuffer();
 163             }
 164             else {
 165                 ++nextToConsume;
 166                 boolean hasNext = nextToConsume < buffer.count();
 167                 if (!hasNext) {
 168                     nextToConsume = 0;
 169                     buffer.clear();
 170                     hasNext = fillBuffer();
 171                 }
 172                 return hasNext;
 173             }
 174         }
 175 
 176         /**
 177          * Invokes the shape-specific constructor with the provided arguments
 178          * and returns the result.
 179          */
 180         abstract AbstractWrappingSpliterator<P_IN, P_OUT, T_BUFFER> wrap(Spliterator<P_IN> s);
 181 
 182         /**
 183          * Initializes buffer, sink chain, and pusher for a shape-specific
 184          * implementation.
 185          */
 186         abstract void initPartialTraversalState();
 187 
 188         void initPusher() {
 189             pusher = () -> spliterator.tryAdvance(bufferSink);
 190         }
 191 
 192         @Override
 193         public Spliterator<P_OUT> trySplit() {
 194             if (isParallel && !finished) {
 195                 init();
 196 
 197                 Spliterator<P_IN> split = spliterator.trySplit();
 198                 if (split == null)
 199                     return null;
 200                 AbstractWrappingSpliterator<P_IN, P_OUT, T_BUFFER> prefix = wrap(split);
 201                 if (buffer != null) {
 202                     prefix.buffer = buffer;
 203                     prefix.bufferSink = bufferSink;
 204                     prefix.nextToConsume = nextToConsume;
 205                     prefix.initPusher();
 206                     buffer = null;
 207                 }
 208                 return prefix;
 209             }
 210             else
 211                 return null;
 212         }
 213 
 214         /**
 215          * If the buffer is empty, push elements into the sink chain until
 216          * the source is empty or cancellation is requested.
 217          * @return whether there are elements to consume from the buffer
 218          */
 219         private boolean fillBuffer() {
 220             while (buffer.count() == 0) {
 221                 if (bufferSink.cancellationRequested() || !pusher.getAsBoolean()) {
 222                     if (finished)
 223                         return false;
 224                     else {
 225                         bufferSink.end(); // might trigger more elements
 226                         finished = true;
 227                     }
 228                 }


 289                             boolean parallel) {
 290             super(ph, supplier, parallel);
 291         }
 292 
 293         WrappingSpliterator(PipelineHelper<P_OUT> ph,
 294                             Spliterator<P_IN> spliterator,
 295                             boolean parallel) {
 296             super(ph, spliterator, parallel);
 297         }
 298 
 299         @Override
 300         WrappingSpliterator<P_IN, P_OUT> wrap(Spliterator<P_IN> s) {
 301             return new WrappingSpliterator<>(ph, s, isParallel);
 302         }
 303 
 304         @Override
 305         void initPartialTraversalState() {
 306             SpinedBuffer<P_OUT> b = new SpinedBuffer<>();
 307             buffer = b;
 308             bufferSink = ph.wrapSink(b::accept);

 309         }
 310 
 311         @Override
 312         public boolean tryAdvance(Consumer<? super P_OUT> consumer) {
 313             Objects.requireNonNull(consumer);
 314             boolean hasNext = doAdvance();
 315             if (hasNext)
 316                 consumer.accept(buffer.get(nextToConsume));
 317             return hasNext;
 318         }
 319 
 320         @Override
 321         public void forEachRemaining(Consumer<? super P_OUT> consumer) {
 322             if (buffer == null && !finished) {
 323                 Objects.requireNonNull(consumer);
 324                 init();
 325 
 326                 ph.wrapAndCopyInto((Sink<P_OUT>) consumer::accept, spliterator);
 327                 finished = true;
 328             }


 332         }
 333     }
 334 
 335     static final class IntWrappingSpliterator<P_IN>
 336             extends AbstractWrappingSpliterator<P_IN, Integer, SpinedBuffer.OfInt>
 337             implements Spliterator.OfInt {
 338 
 339         IntWrappingSpliterator(PipelineHelper<Integer> ph,
 340                                Supplier<Spliterator<P_IN>> supplier,
 341                                boolean parallel) {
 342             super(ph, supplier, parallel);
 343         }
 344 
 345         IntWrappingSpliterator(PipelineHelper<Integer> ph,
 346                                Spliterator<P_IN> spliterator,
 347                                boolean parallel) {
 348             super(ph, spliterator, parallel);
 349         }
 350 
 351         @Override
 352         AbstractWrappingSpliterator<P_IN, Integer, SpinedBuffer.OfInt> wrap(Spliterator<P_IN> s) {
 353             return new IntWrappingSpliterator<>(ph, s, isParallel);
 354         }
 355 
 356         @Override
 357         void initPartialTraversalState() {
 358             SpinedBuffer.OfInt b = new SpinedBuffer.OfInt();
 359             buffer = b;
 360             bufferSink = ph.wrapSink((Sink.OfInt) b::accept);

 361         }
 362 
 363         @Override
 364         public Spliterator.OfInt trySplit() {
 365             return (Spliterator.OfInt) super.trySplit();
 366         }
 367 
 368         @Override
 369         public boolean tryAdvance(IntConsumer consumer) {
 370             Objects.requireNonNull(consumer);
 371             boolean hasNext = doAdvance();
 372             if (hasNext)
 373                 consumer.accept(buffer.get(nextToConsume));
 374             return hasNext;
 375         }
 376 
 377         @Override
 378         public void forEachRemaining(IntConsumer consumer) {
 379             if (buffer == null && !finished) {
 380                 Objects.requireNonNull(consumer);


 389         }
 390     }
 391 
 392     static final class LongWrappingSpliterator<P_IN>
 393             extends AbstractWrappingSpliterator<P_IN, Long, SpinedBuffer.OfLong>
 394             implements Spliterator.OfLong {
 395 
 396         LongWrappingSpliterator(PipelineHelper<Long> ph,
 397                                 Supplier<Spliterator<P_IN>> supplier,
 398                                 boolean parallel) {
 399             super(ph, supplier, parallel);
 400         }
 401 
 402         LongWrappingSpliterator(PipelineHelper<Long> ph,
 403                                 Spliterator<P_IN> spliterator,
 404                                 boolean parallel) {
 405             super(ph, spliterator, parallel);
 406         }
 407 
 408         @Override
 409         AbstractWrappingSpliterator<P_IN, Long, SpinedBuffer.OfLong> wrap(Spliterator<P_IN> s) {
 410             return new LongWrappingSpliterator<>(ph, s, isParallel);
 411         }
 412 
 413         @Override
 414         void initPartialTraversalState() {
 415             SpinedBuffer.OfLong b = new SpinedBuffer.OfLong();
 416             buffer = b;
 417             bufferSink = ph.wrapSink((Sink.OfLong) b::accept);

 418         }
 419 
 420         @Override
 421         public Spliterator.OfLong trySplit() {
 422             return (Spliterator.OfLong) super.trySplit();
 423         }
 424 
 425         @Override
 426         public boolean tryAdvance(LongConsumer consumer) {
 427             Objects.requireNonNull(consumer);
 428             boolean hasNext = doAdvance();
 429             if (hasNext)
 430                 consumer.accept(buffer.get(nextToConsume));
 431             return hasNext;
 432         }
 433 
 434         @Override
 435         public void forEachRemaining(LongConsumer consumer) {
 436             if (buffer == null && !finished) {
 437                 Objects.requireNonNull(consumer);


 446         }
 447     }
 448 
 449     static final class DoubleWrappingSpliterator<P_IN>
 450             extends AbstractWrappingSpliterator<P_IN, Double, SpinedBuffer.OfDouble>
 451             implements Spliterator.OfDouble {
 452 
 453         DoubleWrappingSpliterator(PipelineHelper<Double> ph,
 454                                   Supplier<Spliterator<P_IN>> supplier,
 455                                   boolean parallel) {
 456             super(ph, supplier, parallel);
 457         }
 458 
 459         DoubleWrappingSpliterator(PipelineHelper<Double> ph,
 460                                   Spliterator<P_IN> spliterator,
 461                                   boolean parallel) {
 462             super(ph, spliterator, parallel);
 463         }
 464 
 465         @Override
 466         AbstractWrappingSpliterator<P_IN, Double, SpinedBuffer.OfDouble> wrap(Spliterator<P_IN> s) {
 467             return new DoubleWrappingSpliterator<>(ph, s, isParallel);
 468         }
 469 
 470         @Override
 471         void initPartialTraversalState() {
 472             SpinedBuffer.OfDouble b = new SpinedBuffer.OfDouble();
 473             buffer = b;
 474             bufferSink = ph.wrapSink((Sink.OfDouble) b::accept);

 475         }
 476 
 477         @Override
 478         public Spliterator.OfDouble trySplit() {
 479             return (Spliterator.OfDouble) super.trySplit();
 480         }
 481 
 482         @Override
 483         public boolean tryAdvance(DoubleConsumer consumer) {
 484             Objects.requireNonNull(consumer);
 485             boolean hasNext = doAdvance();
 486             if (hasNext)
 487                 consumer.accept(buffer.get(nextToConsume));
 488             return hasNext;
 489         }
 490 
 491         @Override
 492         public void forEachRemaining(DoubleConsumer consumer) {
 493             if (buffer == null && !finished) {
 494                 Objects.requireNonNull(consumer);


< prev index next >