1 /* 2 * Copyright (c) 2012, 2013, 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.Comparator; 28 import java.util.Iterator; 29 import java.util.Objects; 30 import java.util.Optional; 31 import java.util.Spliterator; 32 import java.util.Spliterators; 33 import java.util.function.BiConsumer; 34 import java.util.function.BiFunction; 35 import java.util.function.BinaryOperator; 36 import java.util.function.Consumer; 37 import java.util.function.DoubleConsumer; 38 import java.util.function.Function; 39 import java.util.function.IntConsumer; 40 import java.util.function.IntFunction; 41 import java.util.function.LongConsumer; 42 import java.util.function.Predicate; 43 import java.util.function.Supplier; 44 import java.util.function.ToDoubleFunction; 45 import java.util.function.ToIntFunction; 46 import java.util.function.ToLongFunction; 47 48 /** 49 * Abstract base class for an intermediate pipeline stage or pipeline source 50 * stage implementing whose elements are of type {@code U}. 51 * 52 * @param <P_IN> type of elements in the upstream source 53 * @param <P_OUT> type of elements in produced by this stage 54 * 55 * @since 1.8 56 * @hide Visible for CTS testing only (OpenJDK8 tests). 57 */ 58 // Android-changed: Made public for CTS tests only. 59 public abstract class ReferencePipeline<P_IN, P_OUT> 60 extends AbstractPipeline<P_IN, P_OUT, Stream<P_OUT>> 61 implements Stream<P_OUT> { 62 63 /** 64 * Constructor for the head of a stream pipeline. 65 * 66 * @param source {@code Supplier<Spliterator>} describing the stream source 67 * @param sourceFlags the source flags for the stream source, described in 68 * {@link StreamOpFlag} 69 * @param parallel {@code true} if the pipeline is parallel 70 */ ReferencePipeline(Supplier<? extends Spliterator<?>> source, int sourceFlags, boolean parallel)71 ReferencePipeline(Supplier<? extends Spliterator<?>> source, 72 int sourceFlags, boolean parallel) { 73 super(source, sourceFlags, parallel); 74 } 75 76 /** 77 * Constructor for the head of a stream pipeline. 78 * 79 * @param source {@code Spliterator} describing the stream source 80 * @param sourceFlags The source flags for the stream source, described in 81 * {@link StreamOpFlag} 82 * @param parallel {@code true} if the pipeline is parallel 83 */ ReferencePipeline(Spliterator<?> source, int sourceFlags, boolean parallel)84 ReferencePipeline(Spliterator<?> source, 85 int sourceFlags, boolean parallel) { 86 super(source, sourceFlags, parallel); 87 } 88 89 /** 90 * Constructor for appending an intermediate operation onto an existing 91 * pipeline. 92 * 93 * @param upstream the upstream element source. 94 */ ReferencePipeline(AbstractPipeline<?, P_IN, ?> upstream, int opFlags)95 ReferencePipeline(AbstractPipeline<?, P_IN, ?> upstream, int opFlags) { 96 super(upstream, opFlags); 97 } 98 99 // Shape-specific methods 100 101 @Override 102 // Android-changed: Make public, to match the method it's overriding. getOutputShape()103 public final StreamShape getOutputShape() { 104 return StreamShape.REFERENCE; 105 } 106 107 @Override 108 // Android-changed: Make public, to match the method it's overriding. evaluateToNode(PipelineHelper<P_OUT> helper, Spliterator<P_IN> spliterator, boolean flattenTree, IntFunction<P_OUT[]> generator)109 public final <P_IN> Node<P_OUT> evaluateToNode(PipelineHelper<P_OUT> helper, 110 Spliterator<P_IN> spliterator, 111 boolean flattenTree, 112 IntFunction<P_OUT[]> generator) { 113 return Nodes.collect(helper, spliterator, flattenTree, generator); 114 } 115 116 @Override 117 // Android-changed: Make public, to match the method it's overriding. wrap(PipelineHelper<P_OUT> ph, Supplier<Spliterator<P_IN>> supplier, boolean isParallel)118 public final <P_IN> Spliterator<P_OUT> wrap(PipelineHelper<P_OUT> ph, 119 Supplier<Spliterator<P_IN>> supplier, 120 boolean isParallel) { 121 return new StreamSpliterators.WrappingSpliterator<>(ph, supplier, isParallel); 122 } 123 124 @Override 125 // Android-changed: Make public, to match the method it's overriding. lazySpliterator(Supplier<? extends Spliterator<P_OUT>> supplier)126 public final Spliterator<P_OUT> lazySpliterator(Supplier<? extends Spliterator<P_OUT>> supplier) { 127 return new StreamSpliterators.DelegatingSpliterator<>(supplier); 128 } 129 130 @Override 131 // Android-changed: Make public, to match the method it's overriding. forEachWithCancel(Spliterator<P_OUT> spliterator, Sink<P_OUT> sink)132 public final void forEachWithCancel(Spliterator<P_OUT> spliterator, Sink<P_OUT> sink) { 133 do { } while (!sink.cancellationRequested() && spliterator.tryAdvance(sink)); 134 } 135 136 @Override 137 // Android-changed: Make public, to match the method it's overriding. makeNodeBuilder(long exactSizeIfKnown, IntFunction<P_OUT[]> generator)138 public final Node.Builder<P_OUT> makeNodeBuilder(long exactSizeIfKnown, IntFunction<P_OUT[]> generator) { 139 return Nodes.builder(exactSizeIfKnown, generator); 140 } 141 142 143 // BaseStream 144 145 @Override iterator()146 public final Iterator<P_OUT> iterator() { 147 return Spliterators.iterator(spliterator()); 148 } 149 150 151 // Stream 152 153 // Stateless intermediate operations from Stream 154 155 @Override unordered()156 public Stream<P_OUT> unordered() { 157 if (!isOrdered()) 158 return this; 159 return new StatelessOp<P_OUT, P_OUT>(this, StreamShape.REFERENCE, StreamOpFlag.NOT_ORDERED) { 160 @Override 161 // Android-changed: Make public, to match the method it's overriding. 162 public Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) { 163 return sink; 164 } 165 }; 166 } 167 168 @Override 169 public final Stream<P_OUT> filter(Predicate<? super P_OUT> predicate) { 170 Objects.requireNonNull(predicate); 171 return new StatelessOp<P_OUT, P_OUT>(this, StreamShape.REFERENCE, 172 StreamOpFlag.NOT_SIZED) { 173 @Override 174 // Android-changed: Make public, to match the method it's overriding. 175 public Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) { 176 return new Sink.ChainedReference<P_OUT, P_OUT>(sink) { 177 @Override 178 public void begin(long size) { 179 downstream.begin(-1); 180 } 181 182 @Override 183 public void accept(P_OUT u) { 184 if (predicate.test(u)) 185 downstream.accept(u); 186 } 187 }; 188 } 189 }; 190 } 191 192 @Override 193 @SuppressWarnings("unchecked") 194 public final <R> Stream<R> map(Function<? super P_OUT, ? extends R> mapper) { 195 Objects.requireNonNull(mapper); 196 return new StatelessOp<P_OUT, R>(this, StreamShape.REFERENCE, 197 StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { 198 @Override 199 public Sink<P_OUT> opWrapSink(int flags, Sink<R> sink) { 200 return new Sink.ChainedReference<P_OUT, R>(sink) { 201 @Override 202 public void accept(P_OUT u) { 203 downstream.accept(mapper.apply(u)); 204 } 205 }; 206 } 207 }; 208 } 209 210 @Override 211 public final IntStream mapToInt(ToIntFunction<? super P_OUT> mapper) { 212 Objects.requireNonNull(mapper); 213 return new IntPipeline.StatelessOp<P_OUT>(this, StreamShape.REFERENCE, 214 StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { 215 @Override 216 // Android-changed: Make public, to match the method it's overriding. 217 public Sink<P_OUT> opWrapSink(int flags, Sink<Integer> sink) { 218 return new Sink.ChainedReference<P_OUT, Integer>(sink) { 219 @Override 220 public void accept(P_OUT u) { 221 downstream.accept(mapper.applyAsInt(u)); 222 } 223 }; 224 } 225 }; 226 } 227 228 @Override 229 public final LongStream mapToLong(ToLongFunction<? super P_OUT> mapper) { 230 Objects.requireNonNull(mapper); 231 return new LongPipeline.StatelessOp<P_OUT>(this, StreamShape.REFERENCE, 232 StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { 233 @Override 234 // Android-changed: Make public, to match the method it's overriding. 235 public Sink<P_OUT> opWrapSink(int flags, Sink<Long> sink) { 236 return new Sink.ChainedReference<P_OUT, Long>(sink) { 237 @Override 238 public void accept(P_OUT u) { 239 downstream.accept(mapper.applyAsLong(u)); 240 } 241 }; 242 } 243 }; 244 } 245 246 @Override 247 public final DoubleStream mapToDouble(ToDoubleFunction<? super P_OUT> mapper) { 248 Objects.requireNonNull(mapper); 249 return new DoublePipeline.StatelessOp<P_OUT>(this, StreamShape.REFERENCE, 250 StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { 251 @Override 252 // Android-changed: Make public, to match the method it's overriding. 253 public Sink<P_OUT> opWrapSink(int flags, Sink<Double> sink) { 254 return new Sink.ChainedReference<P_OUT, Double>(sink) { 255 @Override 256 public void accept(P_OUT u) { 257 downstream.accept(mapper.applyAsDouble(u)); 258 } 259 }; 260 } 261 }; 262 } 263 264 @Override 265 public final <R> Stream<R> flatMap(Function<? super P_OUT, ? extends Stream<? extends R>> mapper) { 266 Objects.requireNonNull(mapper); 267 // We can do better than this, by polling cancellationRequested when stream is infinite 268 return new StatelessOp<P_OUT, R>(this, StreamShape.REFERENCE, 269 StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { 270 @Override 271 public Sink<P_OUT> opWrapSink(int flags, Sink<R> sink) { 272 return new Sink.ChainedReference<P_OUT, R>(sink) { 273 @Override 274 public void begin(long size) { 275 downstream.begin(-1); 276 } 277 278 @Override 279 public void accept(P_OUT u) { 280 try (Stream<? extends R> result = mapper.apply(u)) { 281 // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it 282 if (result != null) 283 result.sequential().forEach(downstream); 284 } 285 } 286 }; 287 } 288 }; 289 } 290 291 @Override 292 public final IntStream flatMapToInt(Function<? super P_OUT, ? extends IntStream> mapper) { 293 Objects.requireNonNull(mapper); 294 // We can do better than this, by polling cancellationRequested when stream is infinite 295 return new IntPipeline.StatelessOp<P_OUT>(this, StreamShape.REFERENCE, 296 StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { 297 @Override 298 // Android-changed: Make public, to match the method it's overriding. 299 public Sink<P_OUT> opWrapSink(int flags, Sink<Integer> sink) { 300 return new Sink.ChainedReference<P_OUT, Integer>(sink) { 301 IntConsumer downstreamAsInt = downstream::accept; 302 @Override 303 public void begin(long size) { 304 downstream.begin(-1); 305 } 306 307 @Override 308 public void accept(P_OUT u) { 309 try (IntStream result = mapper.apply(u)) { 310 // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it 311 if (result != null) 312 result.sequential().forEach(downstreamAsInt); 313 } 314 } 315 }; 316 } 317 }; 318 } 319 320 @Override 321 public final DoubleStream flatMapToDouble(Function<? super P_OUT, ? extends DoubleStream> mapper) { 322 Objects.requireNonNull(mapper); 323 // We can do better than this, by polling cancellationRequested when stream is infinite 324 return new DoublePipeline.StatelessOp<P_OUT>(this, StreamShape.REFERENCE, 325 StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { 326 @Override 327 // Android-changed: Make public, to match the method it's overriding. 328 public Sink<P_OUT> opWrapSink(int flags, Sink<Double> sink) { 329 return new Sink.ChainedReference<P_OUT, Double>(sink) { 330 DoubleConsumer downstreamAsDouble = downstream::accept; 331 @Override 332 public void begin(long size) { 333 downstream.begin(-1); 334 } 335 336 @Override 337 public void accept(P_OUT u) { 338 try (DoubleStream result = mapper.apply(u)) { 339 // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it 340 if (result != null) 341 result.sequential().forEach(downstreamAsDouble); 342 } 343 } 344 }; 345 } 346 }; 347 } 348 349 @Override 350 public final LongStream flatMapToLong(Function<? super P_OUT, ? extends LongStream> mapper) { 351 Objects.requireNonNull(mapper); 352 // We can do better than this, by polling cancellationRequested when stream is infinite 353 return new LongPipeline.StatelessOp<P_OUT>(this, StreamShape.REFERENCE, 354 StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { 355 @Override 356 // Android-changed: Make public, to match the method it's overriding. 357 public Sink<P_OUT> opWrapSink(int flags, Sink<Long> sink) { 358 return new Sink.ChainedReference<P_OUT, Long>(sink) { 359 LongConsumer downstreamAsLong = downstream::accept; 360 @Override 361 public void begin(long size) { 362 downstream.begin(-1); 363 } 364 365 @Override 366 public void accept(P_OUT u) { 367 try (LongStream result = mapper.apply(u)) { 368 // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it 369 if (result != null) 370 result.sequential().forEach(downstreamAsLong); 371 } 372 } 373 }; 374 } 375 }; 376 } 377 378 @Override 379 public final Stream<P_OUT> peek(Consumer<? super P_OUT> action) { 380 Objects.requireNonNull(action); 381 return new StatelessOp<P_OUT, P_OUT>(this, StreamShape.REFERENCE, 382 0) { 383 @Override 384 // Android-changed: Make public, to match the method it's overriding. 385 public Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) { 386 return new Sink.ChainedReference<P_OUT, P_OUT>(sink) { 387 @Override 388 public void accept(P_OUT u) { 389 action.accept(u); 390 downstream.accept(u); 391 } 392 }; 393 } 394 }; 395 } 396 397 // Stateful intermediate operations from Stream 398 399 @Override 400 public final Stream<P_OUT> distinct() { 401 return DistinctOps.makeRef(this); 402 } 403 404 @Override 405 public final Stream<P_OUT> sorted() { 406 return SortedOps.makeRef(this); 407 } 408 409 @Override 410 public final Stream<P_OUT> sorted(Comparator<? super P_OUT> comparator) { 411 return SortedOps.makeRef(this, comparator); 412 } 413 414 @Override 415 public final Stream<P_OUT> limit(long maxSize) { 416 if (maxSize < 0) 417 throw new IllegalArgumentException(Long.toString(maxSize)); 418 return SliceOps.makeRef(this, 0, maxSize); 419 } 420 421 @Override 422 public final Stream<P_OUT> skip(long n) { 423 if (n < 0) 424 throw new IllegalArgumentException(Long.toString(n)); 425 if (n == 0) 426 return this; 427 else 428 return SliceOps.makeRef(this, n, -1); 429 } 430 431 // Terminal operations from Stream 432 433 @Override 434 public void forEach(Consumer<? super P_OUT> action) { 435 evaluate(ForEachOps.makeRef(action, false)); 436 } 437 438 @Override 439 public void forEachOrdered(Consumer<? super P_OUT> action) { 440 evaluate(ForEachOps.makeRef(action, true)); 441 } 442 443 @Override 444 @SuppressWarnings("unchecked") 445 public final <A> A[] toArray(IntFunction<A[]> generator) { 446 // Since A has no relation to U (not possible to declare that A is an upper bound of U) 447 // there will be no static type checking. 448 // Therefore use a raw type and assume A == U rather than propagating the separation of A and U 449 // throughout the code-base. 450 // The runtime type of U is never checked for equality with the component type of the runtime type of A[]. 451 // Runtime checking will be performed when an element is stored in A[], thus if A is not a 452 // super type of U an ArrayStoreException will be thrown. 453 @SuppressWarnings("rawtypes") 454 IntFunction rawGenerator = (IntFunction) generator; 455 // Android-changed: Eclipse compiler requires explicit (Node<A[]>) cast (b/29399275). 456 return (A[]) Nodes.flatten((Node<A[]>) evaluateToArrayNode(rawGenerator), rawGenerator) 457 .asArray(rawGenerator); 458 } 459 460 @Override 461 public final Object[] toArray() { 462 return toArray(Object[]::new); 463 } 464 465 @Override 466 public final boolean anyMatch(Predicate<? super P_OUT> predicate) { 467 return evaluate(MatchOps.makeRef(predicate, MatchOps.MatchKind.ANY)); 468 } 469 470 @Override 471 public final boolean allMatch(Predicate<? super P_OUT> predicate) { 472 return evaluate(MatchOps.makeRef(predicate, MatchOps.MatchKind.ALL)); 473 } 474 475 @Override 476 public final boolean noneMatch(Predicate<? super P_OUT> predicate) { 477 return evaluate(MatchOps.makeRef(predicate, MatchOps.MatchKind.NONE)); 478 } 479 480 @Override 481 public final Optional<P_OUT> findFirst() { 482 return evaluate(FindOps.makeRef(true)); 483 } 484 485 @Override 486 public final Optional<P_OUT> findAny() { 487 return evaluate(FindOps.makeRef(false)); 488 } 489 490 @Override 491 public final P_OUT reduce(final P_OUT identity, final BinaryOperator<P_OUT> accumulator) { 492 return evaluate(ReduceOps.makeRef(identity, accumulator, accumulator)); 493 } 494 495 @Override 496 public final Optional<P_OUT> reduce(BinaryOperator<P_OUT> accumulator) { 497 return evaluate(ReduceOps.makeRef(accumulator)); 498 } 499 500 @Override 501 public final <R> R reduce(R identity, BiFunction<R, ? super P_OUT, R> accumulator, BinaryOperator<R> combiner) { 502 return evaluate(ReduceOps.makeRef(identity, accumulator, combiner)); 503 } 504 505 @Override 506 @SuppressWarnings("unchecked") 507 public final <R, A> R collect(Collector<? super P_OUT, A, R> collector) { 508 A container; 509 if (isParallel() 510 && (collector.characteristics().contains(Collector.Characteristics.CONCURRENT)) 511 && (!isOrdered() || collector.characteristics().contains(Collector.Characteristics.UNORDERED))) { 512 container = collector.supplier().get(); 513 BiConsumer<A, ? super P_OUT> accumulator = collector.accumulator(); 514 forEach(u -> accumulator.accept(container, u)); 515 } 516 else { 517 container = evaluate(ReduceOps.makeRef(collector)); 518 } 519 return collector.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH) 520 ? (R) container 521 : collector.finisher().apply(container); 522 } 523 524 @Override 525 public final <R> R collect(Supplier<R> supplier, 526 BiConsumer<R, ? super P_OUT> accumulator, 527 BiConsumer<R, R> combiner) { 528 return evaluate(ReduceOps.makeRef(supplier, accumulator, combiner)); 529 } 530 531 @Override 532 public final Optional<P_OUT> max(Comparator<? super P_OUT> comparator) { 533 return reduce(BinaryOperator.maxBy(comparator)); 534 } 535 536 @Override 537 public final Optional<P_OUT> min(Comparator<? super P_OUT> comparator) { 538 return reduce(BinaryOperator.minBy(comparator)); 539 540 } 541 542 @Override 543 public final long count() { 544 return mapToLong(e -> 1L).sum(); 545 } 546 547 548 // 549 550 /** 551 * Source stage of a ReferencePipeline. 552 * 553 * @param <E_IN> type of elements in the upstream source 554 * @param <E_OUT> type of elements in produced by this stage 555 * @since 1.8 556 * @hide Visible for CTS testing only (OpenJDK8 tests). 557 */ 558 // Android-changed: Made public for CTS tests only. 559 public static class Head<E_IN, E_OUT> extends ReferencePipeline<E_IN, E_OUT> { 560 /** 561 * Constructor for the source stage of a Stream. 562 * 563 * @param source {@code Supplier<Spliterator>} describing the stream 564 * source 565 * @param sourceFlags the source flags for the stream source, described 566 * in {@link StreamOpFlag} 567 */ 568 // Android-changed: Made public for CTS tests only. 569 public Head(Supplier<? extends Spliterator<?>> source, 570 int sourceFlags, boolean parallel) { 571 super(source, sourceFlags, parallel); 572 } 573 574 /** 575 * Constructor for the source stage of a Stream. 576 * 577 * @param source {@code Spliterator} describing the stream source 578 * @param sourceFlags the source flags for the stream source, described 579 * in {@link StreamOpFlag} 580 */ 581 // Android-changed: Made public for CTS tests only. 582 public Head(Spliterator<?> source, 583 int sourceFlags, boolean parallel) { 584 super(source, sourceFlags, parallel); 585 } 586 587 @Override 588 // Android-changed: Make public, to match the method it's overriding. 589 public final boolean opIsStateful() { 590 throw new UnsupportedOperationException(); 591 } 592 593 @Override 594 // Android-changed: Make public, to match the method it's overriding. 595 public final Sink<E_IN> opWrapSink(int flags, Sink<E_OUT> sink) { 596 throw new UnsupportedOperationException(); 597 } 598 599 // Optimized sequential terminal operations for the head of the pipeline 600 601 @Override 602 public void forEach(Consumer<? super E_OUT> action) { 603 if (!isParallel()) { 604 sourceStageSpliterator().forEachRemaining(action); 605 } 606 else { 607 super.forEach(action); 608 } 609 } 610 611 @Override 612 public void forEachOrdered(Consumer<? super E_OUT> action) { 613 if (!isParallel()) { 614 sourceStageSpliterator().forEachRemaining(action); 615 } 616 else { 617 super.forEachOrdered(action); 618 } 619 } 620 } 621 622 /** 623 * Base class for a stateless intermediate stage of a Stream. 624 * 625 * @param <E_IN> type of elements in the upstream source 626 * @param <E_OUT> type of elements in produced by this stage 627 * @since 1.8 628 * @hide Visible for CTS testing only (OpenJDK8 tests). 629 */ 630 // Android-changed: Made public for CTS tests only. 631 public abstract static class StatelessOp<E_IN, E_OUT> 632 extends ReferencePipeline<E_IN, E_OUT> { 633 /** 634 * Construct a new Stream by appending a stateless intermediate 635 * operation to an existing stream. 636 * 637 * @param upstream The upstream pipeline stage 638 * @param inputShape The stream shape for the upstream pipeline stage 639 * @param opFlags Operation flags for the new stage 640 */ 641 // Android-changed: Made public for CTS tests only. 642 public StatelessOp(AbstractPipeline<?, E_IN, ?> upstream, 643 StreamShape inputShape, 644 int opFlags) { 645 super(upstream, opFlags); 646 assert upstream.getOutputShape() == inputShape; 647 } 648 649 @Override 650 // Android-changed: Make public, to match the method it's overriding. 651 public final boolean opIsStateful() { 652 return false; 653 } 654 } 655 656 /** 657 * Base class for a stateful intermediate stage of a Stream. 658 * 659 * @param <E_IN> type of elements in the upstream source 660 * @param <E_OUT> type of elements in produced by this stage 661 * @since 1.8 662 * @hide Visible for CTS testing only (OpenJDK8 tests). 663 */ 664 // Android-changed: Made public for CTS tests only. 665 public abstract static class StatefulOp<E_IN, E_OUT> 666 extends ReferencePipeline<E_IN, E_OUT> { 667 /** 668 * Construct a new Stream by appending a stateful intermediate operation 669 * to an existing stream. 670 * @param upstream The upstream pipeline stage 671 * @param inputShape The stream shape for the upstream pipeline stage 672 * @param opFlags Operation flags for the new stage 673 */ 674 // Android-changed: Made public for CTS tests only. 675 public StatefulOp(AbstractPipeline<?, E_IN, ?> upstream, 676 StreamShape inputShape, 677 int opFlags) { 678 super(upstream, opFlags); 679 assert upstream.getOutputShape() == inputShape; 680 } 681 682 @Override 683 // Android-changed: Make public, to match the method it's overriding. 684 public final boolean opIsStateful() { 685 return true; 686 } 687 688 @Override 689 // Android-changed: Make public, to match the method it's overriding. 690 public abstract <P_IN> Node<E_OUT> opEvaluateParallel(PipelineHelper<E_OUT> helper, 691 Spliterator<P_IN> spliterator, 692 IntFunction<E_OUT[]> generator); 693 } 694 } 695