1 /* 2 * Copyright (c) 2012, 2020, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package java.util.stream; 26 27 import java.util.IntSummaryStatistics; 28 import java.util.Objects; 29 import java.util.OptionalDouble; 30 import java.util.OptionalInt; 31 import java.util.PrimitiveIterator; 32 import java.util.Spliterator; 33 import java.util.Spliterators; 34 import java.util.function.BiConsumer; 35 import java.util.function.BinaryOperator; 36 import java.util.function.IntBinaryOperator; 37 import java.util.function.IntConsumer; 38 import java.util.function.IntFunction; 39 import java.util.function.IntPredicate; 40 import java.util.function.IntToDoubleFunction; 41 import java.util.function.IntToLongFunction; 42 import java.util.function.IntUnaryOperator; 43 import java.util.function.ObjIntConsumer; 44 import java.util.function.Supplier; 45 46 /** 47 * Abstract base class for an intermediate pipeline stage or pipeline source 48 * stage implementing whose elements are of type {@code int}. 49 * 50 * @param <E_IN> type of elements in the upstream source 51 * @since 1.8 52 * @hide Visible for CTS testing only (OpenJDK8 tests). 53 */ 54 // Android-changed: Made public for CTS tests only. 55 public abstract class IntPipeline<E_IN> 56 extends AbstractPipeline<E_IN, Integer, IntStream> 57 implements IntStream { 58 59 /** 60 * Constructor for the head of a stream pipeline. 61 * 62 * @param source {@code Supplier<Spliterator>} describing the stream source 63 * @param sourceFlags The source flags for the stream source, described in 64 * {@link StreamOpFlag} 65 * @param parallel {@code true} if the pipeline is parallel 66 */ IntPipeline(Supplier<? extends Spliterator<Integer>> source, int sourceFlags, boolean parallel)67 IntPipeline(Supplier<? extends Spliterator<Integer>> source, 68 int sourceFlags, boolean parallel) { 69 super(source, sourceFlags, parallel); 70 } 71 72 /** 73 * Constructor for the head of a stream pipeline. 74 * 75 * @param source {@code Spliterator} describing the stream source 76 * @param sourceFlags The source flags for the stream source, described in 77 * {@link StreamOpFlag} 78 * @param parallel {@code true} if the pipeline is parallel 79 */ IntPipeline(Spliterator<Integer> source, int sourceFlags, boolean parallel)80 IntPipeline(Spliterator<Integer> source, 81 int sourceFlags, boolean parallel) { 82 super(source, sourceFlags, parallel); 83 } 84 85 /** 86 * Constructor for appending an intermediate operation onto an existing 87 * pipeline. 88 * 89 * @param upstream the upstream element source 90 * @param opFlags the operation flags for the new operation 91 */ IntPipeline(AbstractPipeline<?, E_IN, ?> upstream, int opFlags)92 IntPipeline(AbstractPipeline<?, E_IN, ?> upstream, int opFlags) { 93 super(upstream, opFlags); 94 } 95 96 /** 97 * Adapt a {@code Sink<Integer> to an {@code IntConsumer}, ideally simply 98 * by casting. 99 */ adapt(Sink<Integer> sink)100 private static IntConsumer adapt(Sink<Integer> sink) { 101 if (sink instanceof IntConsumer) { 102 return (IntConsumer) sink; 103 } 104 else { 105 if (Tripwire.ENABLED) 106 Tripwire.trip(AbstractPipeline.class, 107 "using IntStream.adapt(Sink<Integer> s)"); 108 return sink::accept; 109 } 110 } 111 112 /** 113 * Adapt a {@code Spliterator<Integer>} to a {@code Spliterator.OfInt}. 114 * 115 * @implNote 116 * The implementation attempts to cast to a Spliterator.OfInt, and throws an 117 * exception if this cast is not possible. 118 */ adapt(Spliterator<Integer> s)119 private static Spliterator.OfInt adapt(Spliterator<Integer> s) { 120 if (s instanceof Spliterator.OfInt) { 121 return (Spliterator.OfInt) s; 122 } 123 else { 124 if (Tripwire.ENABLED) 125 Tripwire.trip(AbstractPipeline.class, 126 "using IntStream.adapt(Spliterator<Integer> s)"); 127 throw new UnsupportedOperationException("IntStream.adapt(Spliterator<Integer> s)"); 128 } 129 } 130 131 132 // Shape-specific methods 133 134 @Override 135 // Android-changed: Make public, to match the method it's overriding. getOutputShape()136 public final StreamShape getOutputShape() { 137 return StreamShape.INT_VALUE; 138 } 139 140 @Override 141 // Android-changed: Make public, to match the method it's overriding. evaluateToNode(PipelineHelper<Integer> helper, Spliterator<P_IN> spliterator, boolean flattenTree, IntFunction<Integer[]> generator)142 public final <P_IN> Node<Integer> evaluateToNode(PipelineHelper<Integer> helper, 143 Spliterator<P_IN> spliterator, 144 boolean flattenTree, 145 IntFunction<Integer[]> generator) { 146 return Nodes.collectInt(helper, spliterator, flattenTree); 147 } 148 149 @Override 150 // Android-changed: Make public, to match the method it's overriding. wrap(PipelineHelper<Integer> ph, Supplier<Spliterator<P_IN>> supplier, boolean isParallel)151 public final <P_IN> Spliterator<Integer> wrap(PipelineHelper<Integer> ph, 152 Supplier<Spliterator<P_IN>> supplier, 153 boolean isParallel) { 154 return new StreamSpliterators.IntWrappingSpliterator<>(ph, supplier, isParallel); 155 } 156 157 @Override 158 @SuppressWarnings("unchecked") 159 // Android-changed: Make public, to match the method it's overriding. lazySpliterator(Supplier<? extends Spliterator<Integer>> supplier)160 public final Spliterator.OfInt lazySpliterator(Supplier<? extends Spliterator<Integer>> supplier) { 161 return new StreamSpliterators.DelegatingSpliterator.OfInt((Supplier<Spliterator.OfInt>) supplier); 162 } 163 164 @Override 165 // Android-changed: Make public, to match the method it's overriding. forEachWithCancel(Spliterator<Integer> spliterator, Sink<Integer> sink)166 public final boolean forEachWithCancel(Spliterator<Integer> spliterator, Sink<Integer> sink) { 167 Spliterator.OfInt spl = adapt(spliterator); 168 IntConsumer adaptedSink = adapt(sink); 169 boolean cancelled; 170 do { } while (!(cancelled = sink.cancellationRequested()) && spl.tryAdvance(adaptedSink)); 171 return cancelled; 172 } 173 174 @Override 175 // Android-changed: Make public, to match the method it's overriding. makeNodeBuilder(long exactSizeIfKnown, IntFunction<Integer[]> generator)176 public final Node.Builder<Integer> makeNodeBuilder(long exactSizeIfKnown, 177 IntFunction<Integer[]> generator) { 178 return Nodes.intBuilder(exactSizeIfKnown); 179 } 180 mapToObj(IntFunction<? extends U> mapper, int opFlags)181 private <U> Stream<U> mapToObj(IntFunction<? extends U> mapper, int opFlags) { 182 return new ReferencePipeline.StatelessOp<Integer, U>(this, StreamShape.INT_VALUE, opFlags) { 183 @Override 184 // Android-changed: Make public, to match the method it's overriding. 185 public Sink<Integer> opWrapSink(int flags, Sink<U> sink) { 186 return new Sink.ChainedInt<U>(sink) { 187 @Override 188 public void accept(int t) { 189 downstream.accept(mapper.apply(t)); 190 } 191 }; 192 } 193 }; 194 } 195 196 // IntStream 197 198 @Override 199 public final PrimitiveIterator.OfInt iterator() { 200 return Spliterators.iterator(spliterator()); 201 } 202 203 @Override 204 public final Spliterator.OfInt spliterator() { 205 return adapt(super.spliterator()); 206 } 207 208 // Stateless intermediate ops from IntStream 209 210 @Override 211 public final LongStream asLongStream() { 212 return new LongPipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE, 0) { 213 @Override 214 public Sink<Integer> opWrapSink(int flags, Sink<Long> sink) { 215 return new Sink.ChainedInt<Long>(sink) { 216 @Override 217 public void accept(int t) { 218 downstream.accept((long) t); 219 } 220 }; 221 } 222 }; 223 } 224 225 @Override 226 public final DoubleStream asDoubleStream() { 227 return new DoublePipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE, 0) { 228 @Override 229 // Android-changed: Make public, to match the method it's overriding. 230 public Sink<Integer> opWrapSink(int flags, Sink<Double> sink) { 231 return new Sink.ChainedInt<Double>(sink) { 232 @Override 233 public void accept(int t) { 234 downstream.accept((double) t); 235 } 236 }; 237 } 238 }; 239 } 240 241 @Override 242 public final Stream<Integer> boxed() { 243 return mapToObj(Integer::valueOf, 0); 244 } 245 246 @Override 247 public final IntStream map(IntUnaryOperator mapper) { 248 Objects.requireNonNull(mapper); 249 return new StatelessOp<Integer>(this, StreamShape.INT_VALUE, 250 StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { 251 @Override 252 // Android-changed: Make public, to match the method it's overriding. 253 public Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) { 254 return new Sink.ChainedInt<Integer>(sink) { 255 @Override 256 public void accept(int t) { 257 downstream.accept(mapper.applyAsInt(t)); 258 } 259 }; 260 } 261 }; 262 } 263 264 @Override 265 public final <U> Stream<U> mapToObj(IntFunction<? extends U> mapper) { 266 Objects.requireNonNull(mapper); 267 return mapToObj(mapper, StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT); 268 } 269 270 @Override 271 public final LongStream mapToLong(IntToLongFunction mapper) { 272 Objects.requireNonNull(mapper); 273 return new LongPipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE, 274 StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { 275 @Override 276 // Android-changed: Make public, to match the method it's overriding. 277 public Sink<Integer> opWrapSink(int flags, Sink<Long> sink) { 278 return new Sink.ChainedInt<Long>(sink) { 279 @Override 280 public void accept(int t) { 281 downstream.accept(mapper.applyAsLong(t)); 282 } 283 }; 284 } 285 }; 286 } 287 288 @Override 289 public final DoubleStream mapToDouble(IntToDoubleFunction mapper) { 290 Objects.requireNonNull(mapper); 291 return new DoublePipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE, 292 StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { 293 @Override 294 // Android-changed: Make public, to match the method it's overriding. 295 public Sink<Integer> opWrapSink(int flags, Sink<Double> sink) { 296 return new Sink.ChainedInt<Double>(sink) { 297 @Override 298 public void accept(int t) { 299 downstream.accept(mapper.applyAsDouble(t)); 300 } 301 }; 302 } 303 }; 304 } 305 306 @Override 307 public final IntStream flatMap(IntFunction<? extends IntStream> mapper) { 308 Objects.requireNonNull(mapper); 309 return new StatelessOp<Integer>(this, StreamShape.INT_VALUE, 310 StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { 311 @Override 312 // Android-changed: Make public, to match the method it's overriding. 313 public Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) { 314 return new Sink.ChainedInt<Integer>(sink) { 315 // true if cancellationRequested() has been called 316 boolean cancellationRequestedCalled; 317 318 // cache the consumer to avoid creation on every accepted element 319 IntConsumer downstreamAsInt = downstream::accept; 320 321 @Override 322 public void begin(long size) { 323 downstream.begin(-1); 324 } 325 326 @Override 327 public void accept(int t) { 328 try (IntStream result = mapper.apply(t)) { 329 if (result != null) { 330 if (!cancellationRequestedCalled) { 331 result.sequential().forEach(downstreamAsInt); 332 } 333 else { 334 var s = result.sequential().spliterator(); 335 do { } while (!downstream.cancellationRequested() && s.tryAdvance(downstreamAsInt)); 336 } 337 } 338 } 339 } 340 341 @Override 342 public boolean cancellationRequested() { 343 // If this method is called then an operation within the stream 344 // pipeline is short-circuiting (see AbstractPipeline.copyInto). 345 // Note that we cannot differentiate between an upstream or 346 // downstream operation 347 cancellationRequestedCalled = true; 348 return downstream.cancellationRequested(); 349 } 350 }; 351 } 352 }; 353 } 354 355 @Override 356 public final IntStream mapMulti(IntMapMultiConsumer mapper) { 357 Objects.requireNonNull(mapper); 358 return new StatelessOp<>(this, StreamShape.INT_VALUE, 359 StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { 360 @Override 361 // Android-changed: Make public, to match the method it's overriding. 362 public Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) { 363 return new Sink.ChainedInt<>(sink) { 364 365 @Override 366 public void begin(long size) { 367 downstream.begin(-1); 368 } 369 370 @Override 371 @SuppressWarnings("unchecked") 372 public void accept(int t) { 373 mapper.accept(t, (IntConsumer) downstream); 374 } 375 }; 376 } 377 }; 378 } 379 380 @Override 381 public IntStream unordered() { 382 if (!isOrdered()) 383 return this; 384 return new StatelessOp<Integer>(this, StreamShape.INT_VALUE, StreamOpFlag.NOT_ORDERED) { 385 @Override 386 // Android-changed: Make public, to match the method it's overriding. 387 public Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) { 388 return sink; 389 } 390 }; 391 } 392 393 @Override 394 public final IntStream filter(IntPredicate predicate) { 395 Objects.requireNonNull(predicate); 396 return new StatelessOp<Integer>(this, StreamShape.INT_VALUE, 397 StreamOpFlag.NOT_SIZED) { 398 @Override 399 // Android-changed: Make public, to match the method it's overriding. 400 public Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) { 401 return new Sink.ChainedInt<Integer>(sink) { 402 @Override 403 public void begin(long size) { 404 downstream.begin(-1); 405 } 406 407 @Override 408 public void accept(int t) { 409 if (predicate.test(t)) 410 downstream.accept(t); 411 } 412 }; 413 } 414 }; 415 } 416 417 @Override 418 public final IntStream peek(IntConsumer action) { 419 Objects.requireNonNull(action); 420 return new StatelessOp<Integer>(this, StreamShape.INT_VALUE, 421 0) { 422 @Override 423 // Android-changed: Make public, to match the method it's overriding. 424 public Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) { 425 return new Sink.ChainedInt<Integer>(sink) { 426 @Override 427 public void accept(int t) { 428 action.accept(t); 429 downstream.accept(t); 430 } 431 }; 432 } 433 }; 434 } 435 436 // Stateful intermediate ops from IntStream 437 438 @Override 439 public final IntStream limit(long maxSize) { 440 if (maxSize < 0) 441 throw new IllegalArgumentException(Long.toString(maxSize)); 442 return SliceOps.makeInt(this, 0, maxSize); 443 } 444 445 @Override 446 public final IntStream skip(long n) { 447 if (n < 0) 448 throw new IllegalArgumentException(Long.toString(n)); 449 if (n == 0) 450 return this; 451 else 452 return SliceOps.makeInt(this, n, -1); 453 } 454 455 @Override 456 public final IntStream takeWhile(IntPredicate predicate) { 457 return WhileOps.makeTakeWhileInt(this, predicate); 458 } 459 460 @Override 461 public final IntStream dropWhile(IntPredicate predicate) { 462 return WhileOps.makeDropWhileInt(this, predicate); 463 } 464 465 @Override 466 public final IntStream sorted() { 467 return SortedOps.makeInt(this); 468 } 469 470 @Override 471 public final IntStream distinct() { 472 // While functional and quick to implement, this approach is not very efficient. 473 // An efficient version requires an int-specific map/set implementation. 474 return boxed().distinct().mapToInt(i -> i); 475 } 476 477 // Terminal ops from IntStream 478 479 @Override 480 public void forEach(IntConsumer action) { 481 evaluate(ForEachOps.makeInt(action, false)); 482 } 483 484 @Override 485 public void forEachOrdered(IntConsumer action) { 486 evaluate(ForEachOps.makeInt(action, true)); 487 } 488 489 @Override 490 public final int sum() { 491 return reduce(0, Integer::sum); 492 } 493 494 @Override 495 public final OptionalInt min() { 496 return reduce(Math::min); 497 } 498 499 @Override 500 public final OptionalInt max() { 501 return reduce(Math::max); 502 } 503 504 @Override 505 public final long count() { 506 return evaluate(ReduceOps.makeIntCounting()); 507 } 508 509 @Override 510 public final OptionalDouble average() { 511 long[] avg = collect(() -> new long[2], 512 (ll, i) -> { 513 ll[0]++; 514 ll[1] += i; 515 }, 516 (ll, rr) -> { 517 ll[0] += rr[0]; 518 ll[1] += rr[1]; 519 }); 520 return avg[0] > 0 521 ? OptionalDouble.of((double) avg[1] / avg[0]) 522 : OptionalDouble.empty(); 523 } 524 525 @Override 526 public final IntSummaryStatistics summaryStatistics() { 527 return collect(IntSummaryStatistics::new, IntSummaryStatistics::accept, 528 IntSummaryStatistics::combine); 529 } 530 531 @Override 532 public final int reduce(int identity, IntBinaryOperator op) { 533 return evaluate(ReduceOps.makeInt(identity, op)); 534 } 535 536 @Override 537 public final OptionalInt reduce(IntBinaryOperator op) { 538 return evaluate(ReduceOps.makeInt(op)); 539 } 540 541 @Override 542 public final <R> R collect(Supplier<R> supplier, 543 ObjIntConsumer<R> accumulator, 544 BiConsumer<R, R> combiner) { 545 Objects.requireNonNull(combiner); 546 BinaryOperator<R> operator = (left, right) -> { 547 combiner.accept(left, right); 548 return left; 549 }; 550 return evaluate(ReduceOps.makeInt(supplier, accumulator, operator)); 551 } 552 553 @Override 554 public final boolean anyMatch(IntPredicate predicate) { 555 return evaluate(MatchOps.makeInt(predicate, MatchOps.MatchKind.ANY)); 556 } 557 558 @Override 559 public final boolean allMatch(IntPredicate predicate) { 560 return evaluate(MatchOps.makeInt(predicate, MatchOps.MatchKind.ALL)); 561 } 562 563 @Override 564 public final boolean noneMatch(IntPredicate predicate) { 565 return evaluate(MatchOps.makeInt(predicate, MatchOps.MatchKind.NONE)); 566 } 567 568 @Override 569 public final OptionalInt findFirst() { 570 return evaluate(FindOps.makeInt(true)); 571 } 572 573 @Override 574 public final OptionalInt findAny() { 575 return evaluate(FindOps.makeInt(false)); 576 } 577 578 @Override 579 public final int[] toArray() { 580 return Nodes.flattenInt((Node.OfInt) evaluateToArrayNode(Integer[]::new)) 581 .asPrimitiveArray(); 582 } 583 584 // 585 586 /** 587 * Source stage of an IntStream. 588 * 589 * @param <E_IN> type of elements in the upstream source 590 * @since 1.8 591 * @hide Visible for CTS testing only (OpenJDK8 tests). 592 */ 593 // Android-changed: Made public for CTS tests only. 594 public static class Head<E_IN> extends IntPipeline<E_IN> { 595 /** 596 * Constructor for the source stage of an IntStream. 597 * 598 * @param source {@code Supplier<Spliterator>} describing the stream 599 * source 600 * @param sourceFlags the source flags for the stream source, described 601 * in {@link StreamOpFlag} 602 * @param parallel {@code true} if the pipeline is parallel 603 */ 604 // Android-changed: Made public for CTS tests only. 605 public Head(Supplier<? extends Spliterator<Integer>> source, 606 int sourceFlags, boolean parallel) { 607 super(source, sourceFlags, parallel); 608 } 609 610 /** 611 * Constructor for the source stage of an IntStream. 612 * 613 * @param source {@code Spliterator} describing the stream source 614 * @param sourceFlags the source flags for the stream source, described 615 * in {@link StreamOpFlag} 616 * @param parallel {@code true} if the pipeline is parallel 617 */ 618 // Android-changed: Made public for CTS tests only. 619 public Head(Spliterator<Integer> source, 620 int sourceFlags, boolean parallel) { 621 super(source, sourceFlags, parallel); 622 } 623 624 @Override 625 // Android-changed: Make public, to match the method it's overriding. 626 public final boolean opIsStateful() { 627 throw new UnsupportedOperationException(); 628 } 629 630 @Override 631 // Android-changed: Make public, to match the method it's overriding. 632 public final Sink<E_IN> opWrapSink(int flags, Sink<Integer> sink) { 633 throw new UnsupportedOperationException(); 634 } 635 636 // Optimized sequential terminal operations for the head of the pipeline 637 638 @Override 639 public void forEach(IntConsumer action) { 640 if (!isParallel()) { 641 adapt(sourceStageSpliterator()).forEachRemaining(action); 642 } 643 else { 644 super.forEach(action); 645 } 646 } 647 648 @Override 649 public void forEachOrdered(IntConsumer action) { 650 if (!isParallel()) { 651 adapt(sourceStageSpliterator()).forEachRemaining(action); 652 } 653 else { 654 super.forEachOrdered(action); 655 } 656 } 657 } 658 659 /** 660 * Base class for a stateless intermediate stage of an IntStream 661 * 662 * @param <E_IN> type of elements in the upstream source 663 * @since 1.8 664 * @hide Visible for CTS testing only (OpenJDK8 tests). 665 */ 666 // Android-changed: Made public for CTS tests only. 667 public abstract static class StatelessOp<E_IN> extends IntPipeline<E_IN> { 668 /** 669 * Construct a new IntStream by appending a stateless intermediate 670 * operation to an existing stream. 671 * @param upstream The upstream pipeline stage 672 * @param inputShape The stream shape for the upstream pipeline stage 673 * @param opFlags Operation flags for the new stage 674 */ 675 // Android-changed: Made public for CTS tests only. 676 public StatelessOp(AbstractPipeline<?, E_IN, ?> upstream, 677 StreamShape inputShape, 678 int opFlags) { 679 super(upstream, opFlags); 680 assert upstream.getOutputShape() == inputShape; 681 } 682 683 @Override 684 // Android-changed: Make public, to match the method it's overriding. 685 public final boolean opIsStateful() { 686 return false; 687 } 688 } 689 690 /** 691 * Base class for a stateful intermediate stage of an IntStream. 692 * 693 * @param <E_IN> type of elements in the upstream source 694 * @since 1.8 695 * @hide Visible for CTS testing only (OpenJDK8 tests). 696 */ 697 // Android-changed: Made public for CTS tests only. 698 public abstract static class StatefulOp<E_IN> extends IntPipeline<E_IN> { 699 /** 700 * Construct a new IntStream by appending a stateful intermediate 701 * operation to an existing stream. 702 * @param upstream The upstream pipeline stage 703 * @param inputShape The stream shape for the upstream pipeline stage 704 * @param opFlags Operation flags for the new stage 705 */ 706 // Android-changed: Made public for CTS tests only. 707 public StatefulOp(AbstractPipeline<?, E_IN, ?> upstream, 708 StreamShape inputShape, 709 int opFlags) { 710 super(upstream, opFlags); 711 assert upstream.getOutputShape() == inputShape; 712 } 713 714 @Override 715 // Android-changed: Make public, to match the method it's overriding. 716 public final boolean opIsStateful() { 717 return true; 718 } 719 720 @Override 721 // Android-changed: Make public, to match the method it's overriding. 722 public abstract <P_IN> Node<Integer> opEvaluateParallel(PipelineHelper<Integer> helper, 723 Spliterator<P_IN> spliterator, 724 IntFunction<Integer[]> generator); 725 } 726 } 727