java8新特性-引用流-anyMatch,allMatch,noneMatch
Stream的执行流程参考https://www.cnblogs.com/shigongp/p/17181380.html。
anyMatch判断Stream中是否存在满足断言Predicate的元素。allMatch判断Stream中所有元素是否都满足断言Predicate。noneMatch判断Stream中所有元素是否都不满足断言Predicate。
例子
List<User> users = new ArrayList<>();
users.add(new User("张三",30));
users.add(new User("李四",39));
users.add(new User("王五",20));
boolean anyMatch = users.stream().anyMatch(user -> user.getAge() > 30);
System.out.println(anyMatch);
boolean allMatch = users.stream().allMatch(user -> user.getAge() > 30);
System.out.println(allMatch);
boolean noneMatch = users.stream().noneMatch(user -> user.getAge() > 20);
System.out.println(noneMatch);
输出:

源码分析
ReferencePipeline#anyMatch(Predicate<? super P_OUT> predicate)
public final boolean anyMatch(Predicate<? super P_OUT> predicate) {
return evaluate(MatchOps.makeRef(predicate, MatchOps.MatchKind.ANY));
}
先来看看MatchOps.MatchKind枚举:
enum MatchKind {
/** Do all elements match the predicate? */
ANY(true, true),
/** Do any elements match the predicate? */
ALL(false, false),
/** Do no elements match the predicate? */
NONE(true, false);
private final boolean stopOnPredicateMatches;
private final boolean shortCircuitResult;
private MatchKind(boolean stopOnPredicateMatches,
boolean shortCircuitResult) {
this.stopOnPredicateMatches = stopOnPredicateMatches;
this.shortCircuitResult = shortCircuitResult;
}
}
stopOnPredicateMatches表示断言成立时是否停止继续匹配,shortCircuitResult表示是否短路结果。ANY的stopOnPredicateMatches和shortCircuitResult都为true,因为断言成立时已经得到结果不需要继续往下执行。ALL的stopOnPredicateMatches和shortCircuitResult都为false,因为必须对所有元素执行断言,只有全部成立才会成立。NONE的stopOnPredicateMatches为true因为存在元素断言成立此时已得到结果不需往下执行,shortCircuitResult为false表示可能要遍历所有元素才能得到结果。
现在再来看源码:
public final boolean anyMatch(Predicate<? super P_OUT> predicate) {
return evaluate(MatchOps.makeRef(predicate, MatchOps.MatchKind.ANY));
}
@Override
public final boolean allMatch(Predicate<? super P_OUT> predicate) {
return evaluate(MatchOps.makeRef(predicate, MatchOps.MatchKind.ALL));
}
public final boolean noneMatch(Predicate<? super P_OUT> predicate) {
return evaluate(MatchOps.makeRef(predicate, MatchOps.MatchKind.NONE));
}
anyMatch,allMatch,noneMatch的不同在于MatchKind的不同。
MatchOps#makeRef
public static <T> TerminalOp<T, Boolean> makeRef(Predicate<? super T> predicate,
MatchKind matchKind) {
Objects.requireNonNull(predicate);
Objects.requireNonNull(matchKind);
class MatchSink extends BooleanTerminalSink<T> {
MatchSink() {
super(matchKind);
}
@Override
public void accept(T t) {
if (!stop && predicate.test(t) == matchKind.stopOnPredicateMatches) {
stop = true;
value = matchKind.shortCircuitResult;
}
}
}
return new MatchOp<>(StreamShape.REFERENCE, matchKind, MatchSink::new);
}
MatchOp由MatchSink处理操作。关注MatchSink。
MatchSink#accept
public void accept(T t) {
if (!stop && predicate.test(t) == matchKind.stopOnPredicateMatches) {
stop = true;
value = matchKind.shortCircuitResult;
}
}
stop和value由父类BooleanTerminalSink初始化。stop默认值是false,value默认值是!matchKind.shortCircuitResult。如果accept里面的判断不成立则返回默认的value。即如果都不匹配,anyMatch,allMatch,noneMatch的返回值分别是false,true,true。MatchSink#accept的判断逻辑是stop为false和断言predicate等于matchKind.stopOnPredicateMatches成立时,将value设置为matchKind.shortCircuitResult且stop设为true。stop表示没有得到结果。断言predicate等于matchKind.stopOnPredicateMatches成立表示此时已经得到结果,可将MatchOps.MatchKind的stopOnPredicateMatches,shortCircuitResult字段与anyMatch,allMatch,noneMatch的意思比较即可。

浙公网安备 33010602011771号