Answers:
这是流优化,称为短路。本质上,发生的事情是allMatch
阻止在流上执行不必要的中间操作,因为在知道最终结果时没有必要执行这些中间操作。
好像发生了这种情况:
take"Fred"
peek("Fred")
evaluate("Fred".startsWith("F"))
decide whether the result of allMatch() is known for sure: Not yet
take"Jim"
peek("Jim")
evaluate("Jim".startsWith("F"))
decide whether the result of allMatch() is known for sure: Yes
当"Jim".startsWith("F")
被评估时,结果allMatch(s -> s.startsWith("F"))
肯定是已知的。紧随其后的管道中的值无关紧要"Jim"
,我们知道所有以“ F”开头的值都是false
这并非特定于peek
/ allMatch
组合,存在多个中间和端子短路操作。java.util.stream
包的文档状态:
此外,某些操作被认为是短路操作。如果出现无限输入时中间操作可能会产生有限的流,则该中间操作会短路。如果出现无限输入时,端子操作可能会在有限时间内终止,则该端子操作会发生短路。在管道中进行短路操作是使无限流的处理在有限时间内正常终止的必要条件,但不是充分条件。
将此扩展为有限的流,并且短路操作避免了不必要的流水线步骤的执行,就像您的示例一样。
根据JavaDoc of allMatch():
返回此流的所有元素是否与提供的谓词匹配。如果不需要确定结果,则可能无法对所有元素都评估谓词。如果流为空,则返回{@code true},并且不评估该谓词。
@apiNote
此方法评估流元素上谓词的通用量化(对于所有x P(x))。如果流是空的,则称该定量是空虚的,并且始终为{@code true}(与P(x)无关)。
谓词应用于此流的元素@return {@code true},如果该流的所有元素都与提供的谓词匹配或该流为空,否则为{@code false}
在您的情况下:
1-
p(x) : s -> s.startsWith("F")
X : "Fred"
result : X P(X) = true
2
p(x) : s -> s.startsWith("F")
X : "Jim"
result : X P(X) = false
因为XP(X)= false,所以不会进行进一步评估
boolean result = Arrays.asList("Fred", "Finda", "Fish")
.stream()
.peek(System.out::println)
.allMatch(s -> s.startsWith("F"));
System.out.println("Result "+result);
输出为:
Fred
Finda
Fish
Result true
此处流已完全处理,因为每个元素的xP(x)= true