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的意思比较即可。

posted @ 2023-03-13 22:27  shigp1  阅读(765)  评论(0)    收藏  举报