简体   繁体   中英

Combine Java 8 predicates with disjunction

Suppose I have an array or a list of status, and want to filter a list for elements whose status matches any of the given. So I go on creating a predicate. I started by initializing it with the comparison to the first, then adding more conditions with or , which resulted in the minimal predicate but was a lot of code:

Predicate<Rec> predicate = null;
for (SendStatus status : statuss) {
    Predicate<Rec> innerPred = nr -> nr.getStatus() == status;
    if (predicate == null)
        predicate = innerPred;
    else
        predicate = predicate.or(innerpred);
}

More elegantly, I came up with the following code:

Predicate<Rec> predicate = nr -> false;
for (SendStatus status : statuss) {
    predicate = predicate.or(nr -> nr.getStatus() == status);
}

This looks nicer, but has a useless predicate at the beginning of the chain. Apache Collections had an AnyPredicate that could be composed of any number of predicates, and I'm basically looking for a replacement.

Is this superfluous predicate acceptable? Is there an even more elegant way to write this?

How about this, assuming statuss is a Collection<SendStatus> :

Predicate<Rec> predicate = nr -> statuss.stream().anyMatch(status -> nr.getStatus() == status);

Or this, if statuss is a SendStatus[] :

Predicate<Rec> predicate = nr -> Arrays.stream(statuss).anyMatch(status -> nr.getStatus() == status);

Or do as suggested by @Jerry06 in a comment , which is faster if statuss is a Set<SendStatus> , and simpler than streaming collection solution above:

Predicate<Rec> predicate = nr -> statuss.contains(nr.getStatus());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM