anyMatch returns true when a matching element is found; callers must not assume the predicate visits every element.
Java Stream.anyMatch: stop on a decision, not on every element
Express the question as a predicate
A fraud gate needs to know whether any transaction exceeds a review threshold. A sequential anyMatch can stop once it has enough information. That makes it suitable for a decision, not for sending one notification per transaction. Parallel traversal may evaluate more elements even after the result is known.
An empty stream returns false for anyMatch and true for allMatch. Choose the operation that expresses the business rule for an empty batch, rather than relying on the name alone. A terminal operation consumes its stream.
Keep predicates pure
The predicate should inspect a transaction without mutating shared state. If every record needs validation, use an explicit pass or collect validation results; short-circuiting intentionally skips work once the answer is decided.
Working program
import java.util.Arrays;
import java.util.List;
public class TransactionReviewGate {
public static void main(String[] args) {
List<Integer> transferCents = Arrays.asList(4200, 9800, 750);
boolean needsReview = transferCents.stream()
.anyMatch(cents -> cents > 9000);
boolean emptyBatchNeedsReview = java.util.Collections.<Integer>emptyList()
.stream().anyMatch(cents -> cents > 9000);
System.out.println("needsReview=" + needsReview);
System.out.println("emptyNeedsReview=" + emptyBatchNeedsReview);
}
}Output
needsReview=true
emptyNeedsReview=falseCost and ownership
Worst-case time is O(n) and extra pipeline space is small; the operation may stop earlier when a match is found. A parallel pipeline can spend work beyond the first match, and a predicate with I/O side effects makes both timing and coverage unpredictable.
Common Mistakes
- Do not rely on a predicate running once for every element.
- Do not treat empty-input anyMatch as true.
- Do not use a short-circuit terminal operation as an audit or validation pass.
Read next
Java streams are single-use: create a new pipeline for each pass, Java Stream.peek: observation is not a correctness hook, Java streams: lazy pipelines and bounded results, Java parallel streams: forEach and forEachOrdered have different order contracts.
