< prev index next >

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

Print this page

        

@@ -105,11 +105,11 @@
      * @param <O> the result type of the find operation, typically an optional
      *        type
      */
     private static final class FindOp<T, O> implements TerminalOp<T, O> {
         private final StreamShape shape;
-        final boolean mustFindFirst;
+        final int opFlags;
         final O emptyValue;
         final Predicate<O> presentPredicate;
         final Supplier<TerminalSink<T, O>> sinkSupplier;
 
         /**

@@ -127,20 +127,20 @@
         FindOp(boolean mustFindFirst,
                        StreamShape shape,
                        O emptyValue,
                        Predicate<O> presentPredicate,
                        Supplier<TerminalSink<T, O>> sinkSupplier) {
-            this.mustFindFirst = mustFindFirst;
+            this.opFlags = StreamOpFlag.IS_SHORT_CIRCUIT | (mustFindFirst ? 0 : StreamOpFlag.NOT_ORDERED);
             this.shape = shape;
             this.emptyValue = emptyValue;
             this.presentPredicate = presentPredicate;
             this.sinkSupplier = sinkSupplier;
         }
 
         @Override
         public int getOpFlags() {
-            return StreamOpFlag.IS_SHORT_CIRCUIT | (mustFindFirst ? 0 : StreamOpFlag.NOT_ORDERED);
+            return opFlags;
         }
 
         @Override
         public StreamShape inputShape() {
             return shape;

@@ -154,11 +154,14 @@
         }
 
         @Override
         public <P_IN> O evaluateParallel(PipelineHelper<T> helper,
                                          Spliterator<P_IN> spliterator) {
-            return new FindTask<>(this, helper, spliterator).invoke();
+            // This takes into account the upstream ops flags and the terminal
+            // op flags and therefore takes into account findFirst or findAny
+            boolean mustFindFirst = StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags());
+            return new FindTask<>(this, mustFindFirst, helper, spliterator).invoke();
         }
     }
 
     /**
      * Implementation of @{code TerminalSink} that implements the find

@@ -248,20 +251,24 @@
      */
     @SuppressWarnings("serial")
     private static final class FindTask<P_IN, P_OUT, O>
             extends AbstractShortCircuitTask<P_IN, P_OUT, O, FindTask<P_IN, P_OUT, O>> {
         private final FindOp<P_OUT, O> op;
+        private final boolean mustFindFirst;
 
         FindTask(FindOp<P_OUT, O> op,
+                 boolean mustFindFirst,
                  PipelineHelper<P_OUT> helper,
                  Spliterator<P_IN> spliterator) {
             super(helper, spliterator);
+            this.mustFindFirst = mustFindFirst;
             this.op = op;
         }
 
         FindTask(FindTask<P_IN, P_OUT, O> parent, Spliterator<P_IN> spliterator) {
             super(parent, spliterator);
+            this.mustFindFirst = parent.mustFindFirst;
             this.op = parent.op;
         }
 
         @Override
         protected FindTask<P_IN, P_OUT, O> makeChild(Spliterator<P_IN> spliterator) {

@@ -281,11 +288,11 @@
         }
 
         @Override
         protected O doLeaf() {
             O result = helper.wrapAndCopyInto(op.sinkSupplier.get(), spliterator).get();
-            if (!op.mustFindFirst) {
+            if (!this.mustFindFirst) {
                 if (result != null)
                     shortCircuit(result);
                 return null;
             }
             else {

@@ -298,11 +305,11 @@
             }
         }
 
         @Override
         public void onCompletion(CountedCompleter<?> caller) {
-            if (op.mustFindFirst) {
+            if (this.mustFindFirst) {
                     for (FindTask<P_IN, P_OUT, O> child = leftChild, p = null; child != p;
                          p = child, child = rightChild) {
                     O result = child.getLocalResult();
                     if (result != null && op.presentPredicate.test(result)) {
                         setLocalResult(result);
< prev index next >