< 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 >