< prev index next >
src/java.base/share/classes/java/util/stream/FindOps.java
Print this page
*** 105,115 ****
* @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 O emptyValue;
final Predicate<O> presentPredicate;
final Supplier<TerminalSink<T, O>> sinkSupplier;
/**
--- 105,115 ----
* @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 int opFlags;
final O emptyValue;
final Predicate<O> presentPredicate;
final Supplier<TerminalSink<T, O>> sinkSupplier;
/**
*** 127,146 ****
FindOp(boolean mustFindFirst,
StreamShape shape,
O emptyValue,
Predicate<O> presentPredicate,
Supplier<TerminalSink<T, O>> sinkSupplier) {
! this.mustFindFirst = mustFindFirst;
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);
}
@Override
public StreamShape inputShape() {
return shape;
--- 127,146 ----
FindOp(boolean mustFindFirst,
StreamShape shape,
O emptyValue,
Predicate<O> presentPredicate,
Supplier<TerminalSink<T, O>> sinkSupplier) {
! 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 opFlags;
}
@Override
public StreamShape inputShape() {
return shape;
*** 154,164 ****
}
@Override
public <P_IN> O evaluateParallel(PipelineHelper<T> helper,
Spliterator<P_IN> spliterator) {
! return new FindTask<>(this, helper, spliterator).invoke();
}
}
/**
* Implementation of @{code TerminalSink} that implements the find
--- 154,167 ----
}
@Override
public <P_IN> O evaluateParallel(PipelineHelper<T> helper,
Spliterator<P_IN> spliterator) {
! // 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,267 ****
--- 251,274 ----
*/
@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,291 ****
}
@Override
protected O doLeaf() {
O result = helper.wrapAndCopyInto(op.sinkSupplier.get(), spliterator).get();
! if (!op.mustFindFirst) {
if (result != null)
shortCircuit(result);
return null;
}
else {
--- 288,298 ----
}
@Override
protected O doLeaf() {
O result = helper.wrapAndCopyInto(op.sinkSupplier.get(), spliterator).get();
! if (!this.mustFindFirst) {
if (result != null)
shortCircuit(result);
return null;
}
else {
*** 298,308 ****
}
}
@Override
public void onCompletion(CountedCompleter<?> caller) {
! if (op.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);
--- 305,315 ----
}
}
@Override
public void onCompletion(CountedCompleter<?> caller) {
! 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 >