Reputation: 3295
Given:
List<String> str = Arrays.asList ("my", "pen", "is", "your", "pen");
Predicate<String> test = s -> {
int i = 0;
boolean result = s.contains ("pen");
System.out.print((i++) + ":");
return result;
};
This prints: 0:0:
str.stream().filter(test).findFirst();
And this prints 0:0:0:0:0:
str.stream().filter(test).collect(Collectors.toList());
What confuses me is, no matter it is findFirst or collect, no matter the terminal operation is short-circuiting or not, they both should iterate through each item in the list, right?
So why "0:" is printed twice, not just once, not 5 times, in the first example findFirst?
Upvotes: 0
Views: 1130
Reputation: 28163
What confuses me is, no matter it is findFirst or collect, no matter the terminal operation is short-circuiting or not, they both should iterate through each item in the list, right?
Ability to return without examining the entire stream is exactly what makes an operation (like findFirst
) short-circuiting. See Streams javadoc.
Streams documentation actually makes no promises about how or whether your predicate will be evaluated. It just guarantees that it will return the first element of the stream that matches the predicate.
Upvotes: 6
Reputation: 670
The idea of the first Stream is iterate to find the first occurrence of "pen", so the Predicate iterates the array until finds the first element which matches the condition of the filter. For that reason, you see only two "0:". Official documentation
Upvotes: 2